From b1f80f1ef65f53fd5c37951b9168b2ef06e1413f Mon Sep 17 00:00:00 2001 From: Lester Chan Date: Mon, 18 Sep 2017 17:07:09 +0800 Subject: [PATCH 01/32] Remove Translation link --- README.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/README.md b/README.md index 1e8bbf9..17796ff 100644 --- a/README.md +++ b/README.md @@ -26,9 +26,6 @@ Adds an AJAX rating system for your WordPress site's content. ### Development [https://github.com/lesterchan/wp-postratings](https://github.com/lesterchan/wp-postratings "https://github.com/lesterchan/wp-postratings") -### Translations -[http://dev.wp-plugins.org/browser/wp-postratings/i18n/](http://dev.wp-plugins.org/browser/wp-postratings/i18n/ "http://dev.wp-plugins.org/browser/wp-postratings/i18n/") - ### Credits * Plugin icon by [Freepik](http://www.freepik.com) from [Flaticon](http://www.flaticon.com) * Icons courtesy of [FamFamFam](http://www.famfamfam.com/ "FamFamFam") and [Everaldo](http://www.everaldo.com "Everaldo") From 0afe165a8ab4ff01d6dba0b1e09f6bf3a6684f78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Droz?= Date: Wed, 5 Jul 2017 20:03:11 -0300 Subject: [PATCH 02/32] code cleanup * avoid code/routine duplication especially for postratings_page_admin_most_stats() and get_ratings_images_vote() * use ternary operator where it improve readability * use here-doc where possible * move wp_localize_script() where the_rating() actually display voting form and move part of its logic client-side => code simplification * use document.getElementById() where it makes things simpler and alias jQuery to $j * move some "static" file_exists() outside of loops and use a cleaner way to declare/implode() complex markup * avoid double-escaping, let this task to wpdb() + use wpdb->insert() --- includes/postratings-scripts.php | 45 ++-- js/postratings-js.dev.js | 98 ++++---- wp-postratings.php | 380 ++++++++++++++++--------------- 3 files changed, 265 insertions(+), 258 deletions(-) diff --git a/includes/postratings-scripts.php b/includes/postratings-scripts.php index 04e7c35..8218df8 100644 --- a/includes/postratings-scripts.php +++ b/includes/postratings-scripts.php @@ -42,32 +42,8 @@ function ratings_scripts() { wp_enqueue_style( 'wp-postratings-rtl', plugins_url( 'wp-postratings/css/postratings-css-rtl.css' ), false, WP_POSTRATINGS_VERSION, 'all' ); } } - $postratings_max = intval( get_option( 'postratings_max' ) ); - $postratings_custom = intval( get_option( 'postratings_customrating' ) ); - $postratings_ajax_style = get_option( 'postratings_ajax_style' ); - $postratings_image = get_option( 'postratings_image' ); - $postratings_plugins_url = plugins_url( 'wp-postratings' ); - $postratings_javascript = ''; - if($postratings_custom) { - for($i = 1; $i <= $postratings_max; $i++) { - $postratings_javascript .= 'var ratings_' . $i . '_mouseover_image=new Image();ratings_' . $i . '_mouseover_image.src="' . $postratings_plugins_url . '/images/' . $postratings_image . '/rating_' . $i . '_over.' . RATINGS_IMG_EXT . '";'; - } - } else { - $postratings_javascript = 'var ratings_mouseover_image=new Image();ratings_mouseover_image.src="' . $postratings_plugins_url . '/images/' . $postratings_image . '/rating_over.' . RATINGS_IMG_EXT . '";'; - } - wp_enqueue_script('wp-postratings', plugins_url('wp-postratings/js/postratings-js.js'), array('jquery'), WP_POSTRATINGS_VERSION, true); - wp_localize_script('wp-postratings', 'ratingsL10n', array( - 'plugin_url' => $postratings_plugins_url, - 'ajax_url' => admin_url('admin-ajax.php'), - 'text_wait' => __('Please rate only 1 item at a time.', 'wp-postratings'), - 'image' => $postratings_image, - 'image_ext' => RATINGS_IMG_EXT, - 'max' => $postratings_max, - 'show_loading' => intval($postratings_ajax_style['loading']), - 'show_fading' => intval($postratings_ajax_style['fading']), - 'custom' => $postratings_custom, - 'l10n_print_after' => $postratings_javascript - )); + + wp_enqueue_script('wp-postratings', plugins_url('wp-postratings/js/postratings-js.dev.js'), array('jquery'), WP_POSTRATINGS_VERSION, true); } @@ -83,3 +59,20 @@ function ratings_scripts_admin($hook_suffix) { )); } } + +// this need to be triggered manually +function ratings_script_config() { + $postratings_ajax_style = get_option( 'postratings_ajax_style' ); + + wp_localize_script('wp-postratings', 'ratingsL10n', array( + 'plugin_url' => plugins_url( 'wp-postratings' ), + 'ajax_url' => admin_url('admin-ajax.php'), + 'text_wait' => __('Please rate only 1 item at a time.', 'wp-postratings'), + 'image' => get_option( 'postratings_image' ), + 'image_ext' => RATINGS_IMG_EXT, + 'max' => intval( get_option( 'postratings_max' ) ), + 'show_loading' => intval($postratings_ajax_style['loading']), + 'show_fading' => intval($postratings_ajax_style['fading']), + 'custom' => boolval( get_option( 'postratings_customrating', false ) ), + )); +} diff --git a/js/postratings-js.dev.js b/js/postratings-js.dev.js index d4c5976..b07e542 100644 --- a/js/postratings-js.dev.js +++ b/js/postratings-js.dev.js @@ -17,65 +17,59 @@ // Variables -var post_id = 0; -var post_rating = 0; +var $j = jQuery.noConflict(); var is_being_rated = false; ratingsL10n.custom = parseInt(ratingsL10n.custom); ratingsL10n.max = parseInt(ratingsL10n.max); ratingsL10n.show_loading = parseInt(ratingsL10n.show_loading); ratingsL10n.show_fading = parseInt(ratingsL10n.show_fading); + +var ratings_mouseover_image; +if(ratingsL10n.custom) { + ratings_mouseover_image = []; + for(var i = 1; i <= ratingsL10n.max; i++) { + ratings_mouseover_image[i] = new Image(); + ratings_mouseover_image[i].src = ratingsL10n.plugin_url + "/images/" + ratingsL10n.image + "/rating_" + i + "_over." + ratingsL10n.image_ext ; + } +} else { + ratings_mouseover_image = new Image(); + ratings_mouseover_image.src = ratingsL10n.plugin_url + "/images/" + ratingsL10n.image + "/rating_over." + ratingsL10n.image_ext ; +} + // When User Mouse Over Ratings -function current_rating(id, rating, rating_text) { +function current_rating(post_id, post_rating, rating_text) { if(!is_being_rated) { - post_id = id; - post_rating = rating; if(ratingsL10n.custom && ratingsL10n.max == 2) { - jQuery('#rating_' + post_id + '_' + rating).attr('src', eval('ratings_' + rating + '_mouseover_image.src')); + document.getElementById('rating_' + post_id + '_' + post_rating).src = ratings_mouseover_image[i].src; } else { - for(i = 1; i <= rating; i++) { - if(ratingsL10n.custom) { - jQuery('#rating_' + post_id + '_' + i).attr('src', eval('ratings_' + i + '_mouseover_image.src')); - } else { - jQuery('#rating_' + post_id + '_' + i).attr('src', ratings_mouseover_image.src); - } + for(var i = 1; i <= post_rating; i++) { + console.log("#" + 'rating_' + post_id + '_' + i + ' = ' + ratings_mouseover_image.src); + document.getElementById('rating_' + post_id + '_' + i).src = ratingsL10n.custom ? ratings_mouseover_image[i].src : ratings_mouseover_image.src; } } if(jQuery('#ratings_' + post_id + '_text').length) { - jQuery('#ratings_' + post_id + '_text').show(); - jQuery('#ratings_' + post_id + '_text').html(rating_text); + jQuery('#ratings_' + post_id + '_text').html(rating_text).show(); } } } - // When User Mouse Out Ratings -function ratings_off(rating_score, insert_half, half_rtl) { +function ratings_off(post_id, rating_score, insert_half, half_rtl) { if(!is_being_rated) { - for(i = 1; i <= ratingsL10n.max; i++) { + var baseimg = ratingsL10n.plugin_url + '/images/' + ratingsL10n.image + '/rating' ; + for(var i = 1; i <= ratingsL10n.max; i++) { + var element = document.getElementById('rating_' + post_id + '_' + i); if(i <= rating_score) { - if(ratingsL10n.custom) { - jQuery('#rating_' + post_id + '_' + i).attr('src', ratingsL10n.plugin_url + '/images/' + ratingsL10n.image + '/rating_' + i + '_on.' + ratingsL10n.image_ext); - } else { - jQuery('#rating_' + post_id + '_' + i).attr('src', ratingsL10n.plugin_url + '/images/' + ratingsL10n.image + '/rating_on.' + ratingsL10n.image_ext); - } + element.src = baseimg + (ratingsL10n.custom ? '_' + i : '') + '_on.' + ratingsL10n.image_ext; } else if(i == insert_half) { - if(ratingsL10n.custom) { - jQuery('#rating_' + post_id + '_' + i).attr('src', ratingsL10n.plugin_url + '/images/' + ratingsL10n.image + '/rating_' + i + '_half' + (half_rtl ? '-rtl' : '') + '.' + ratingsL10n.image_ext); - } else { - jQuery('#rating_' + post_id + '_' + i).attr('src', ratingsL10n.plugin_url + '/images/' + ratingsL10n.image + '/rating_half' + (half_rtl ? '-rtl' : '') + '.' + ratingsL10n.image_ext); - } + element.src = baseimg + (ratingsL10n.custom ? '_' + i : '') + '_half' + (half_rtl ? '-rtl' : '') + '.' + ratingsL10n.image_ext; } else { - if(ratingsL10n.custom) { - jQuery('#rating_' + post_id + '_' + i).attr('src', ratingsL10n.plugin_url + '/images/' + ratingsL10n.image + '/rating_' + i + '_off.' + ratingsL10n.image_ext); - } else { - jQuery('#rating_' + post_id + '_' + i).attr('src', ratingsL10n.plugin_url + '/images/' + ratingsL10n.image + '/rating_off.' + ratingsL10n.image_ext); - } + element.src = baseimg + (ratingsL10n.custom ? '_' + i : '') + '_off.' + ratingsL10n.image_ext; } } if(jQuery('#ratings_' + post_id + '_text').length) { - jQuery('#ratings_' + post_id + '_text').hide(); - jQuery('#ratings_' + post_id + '_text').empty(); + jQuery('#ratings_' + post_id + '_text').hide().empty(); } } } @@ -86,13 +80,13 @@ function set_is_being_rated(rated_status) { } // Process Post Ratings Success -function rate_post_success(data) { - jQuery('#post-ratings-' + post_id).html(data); +function rate_post_success(post_id, data) { + $j('#post-ratings-' + post_id).html(data); if(ratingsL10n.show_loading) { - jQuery('#post-ratings-' + post_id + '-loading').hide(); + $j('#post-ratings-' + post_id + '-loading').hide(); } if(ratingsL10n.show_fading) { - jQuery('#post-ratings-' + post_id).fadeTo('def', 1, function () { + $j('#post-ratings-' + post_id).fadeTo('def', 1, function () { set_is_being_rated(false); }); } else { @@ -101,27 +95,33 @@ function rate_post_success(data) { } // Process Post Ratings -function rate_post() { - post_ratings_el = jQuery('#post-ratings-' + post_id); +function rate_post(post_id, post_rating) { + var post_ratings_el = $j('#post-ratings-' + post_id); if(!is_being_rated) { - post_ratings_nonce = jQuery(post_ratings_el).data('nonce'); + var post_ratings_nonce = $j(post_ratings_el).data('nonce'); if(typeof post_ratings_nonce == 'undefined' || post_ratings_nonce == null) - post_ratings_nonce = jQuery(post_ratings_el).attr('data-nonce'); + post_ratings_nonce = $j(post_ratings_el).attr('data-nonce'); set_is_being_rated(true); if(ratingsL10n.show_fading) { - jQuery(post_ratings_el).fadeTo('def', 0, function () { + $j(post_ratings_el).fadeTo('def', 0, function () { if(ratingsL10n.show_loading) { - jQuery('#post-ratings-' + post_id + '-loading').show(); + $j('#post-ratings-' + post_id + '-loading').show(); } - jQuery.ajax({type: 'POST', xhrFields: {withCredentials: true}, dataType: 'html', url: ratingsL10n.ajax_url, data: 'action=postratings&pid=' + post_id + '&rate=' + post_rating + '&postratings_' + post_id + '_nonce=' + post_ratings_nonce, cache: false, success: rate_post_success}); }); } else { if(ratingsL10n.show_loading) { - jQuery('#post-ratings-' + post_id + '-loading').show(); + $j('#post-ratings-' + post_id + '-loading').show(); } - jQuery.ajax({type: 'POST', xhrFields: {withCredentials: true}, dataType: 'html', url: ratingsL10n.ajax_url, data: 'action=postratings&pid=' + post_id + '&rate=' + post_rating + '&postratings_' + post_id + '_nonce=' + post_ratings_nonce, cache: false, success: rate_post_success}); } - } else { + $j.post({xhrFields: {withCredentials: true}, + dataType: 'html', + url: ratingsL10n.ajax_url, + data: 'action=postratings&pid=' + post_id + '&rate=' + post_rating + '&postratings_' + post_id + '_nonce=' + post_ratings_nonce, + cache: false}) + .done(function(data) { rate_post_success(post_id, data); }); + } + + else { alert(ratingsL10n.text_wait); } -} \ No newline at end of file +} diff --git a/wp-postratings.php b/wp-postratings.php index 0e8375c..0a45df3 100644 --- a/wp-postratings.php +++ b/wp-postratings.php @@ -75,7 +75,13 @@ function postratings_init() { } ### Function: Display The Rating For The Post -function the_ratings($start_tag = 'div', $custom_id = 0, $display = true) { +function the_ratings($start_tag = 'div', $custom_id = 0, $display = true /* obsolete */) { + if ($display) echo get_the_ratings($start_tag, $custom_id); + else return get_the_ratings($start_tag, $custom_id); +} + +### Function: Get The Rating For The Post +function get_the_ratings($start_tag = 'div', $custom_id = 0) { global $id; // Allow Custom ID if(intval($custom_id) > 0) { @@ -113,27 +119,21 @@ function the_ratings($start_tag = 'div', $custom_id = 0, $display = true) { } else { $attributes = 'id="post-ratings-'.$ratings_id.'" class="post-ratings"'; } + + // If User Voted Or Is Not Allowed To Rate if($user_voted) { - if(!$display) { - return "<$start_tag $attributes>".the_ratings_results($ratings_id).''.$loading; - } else { - echo "<$start_tag $attributes>".the_ratings_results($ratings_id).''.$loading; - } + return "<$start_tag $attributes>".the_ratings_results($ratings_id).''.$loading; // If User Is Not Allowed To Rate } else if(!check_allowtorate()) { - if(!$display) { - return "<$start_tag $attributes>".the_ratings_results($ratings_id, 0, 0, 0, 1).''.$loading; - } else { - echo "<$start_tag $attributes>".the_ratings_results($ratings_id, 0, 0, 0, 1).''.$loading; - } + return "<$start_tag $attributes>".the_ratings_results($ratings_id, 0, 0, 0, 1).''.$loading; // If User Has Not Voted } else { - if(!$display) { - return "<$start_tag $attributes data-nonce=\"".wp_create_nonce('postratings_'.$ratings_id.'-nonce')."\">".the_ratings_vote($ratings_id).''.$loading; - } else { - echo "<$start_tag $attributes data-nonce=\"".wp_create_nonce('postratings_'.$ratings_id.'-nonce')."\">".the_ratings_vote($ratings_id).''.$loading; - } + ratings_script_config(); + $html_string = ''; + $html_string += '' . "\n"; + + return $html_string . "<$start_tag $attributes data-nonce=\"".wp_create_nonce('postratings_'.$ratings_id.'-nonce')."\">".the_ratings_vote($ratings_id).''.$loading; } } @@ -190,15 +190,12 @@ function check_allowtorate() { // Guests Only case 0: return ! is_user_logged_in(); - break; // Logged-in users only case 1: return is_user_logged_in(); - break; // Users registered on blog (for multisite) case 3: return is_user_member_of_blog(); - break; // Registered Users And Guests case 2: default: @@ -247,11 +244,7 @@ function check_rated( $post_id ) { ### Function: Check Rated By Cookie function check_rated_cookie($post_id) { - if(isset($_COOKIE["rated_$post_id"])) { - return true; - } else { - return false; - } + return (isset($_COOKIE["rated_$post_id"])); } @@ -391,7 +384,7 @@ function get_ipaddress() { $ip_address = explode(',', $ip_address); $ip_address = $ip_address[0]; } - return esc_attr($ip_address); + return $ip_address; } } @@ -507,21 +500,21 @@ function delete_ratings_fields($post_ID) { function process_ratings() { global $wpdb, $user_identity, $user_ID; - if(isset($_REQUEST['action']) && $_REQUEST['action'] == 'postratings') - { + if(isset($_REQUEST['action']) && $_REQUEST['action'] == 'postratings') { $rate = intval($_REQUEST['rate']); $post_id = intval($_REQUEST['pid']); // Verify Referer - if(!check_ajax_referer('postratings_'.$post_id.'-nonce', 'postratings_'.$post_id.'_nonce', false)) - { + if(!check_ajax_referer('postratings_'.$post_id.'-nonce', 'postratings_'.$post_id.'_nonce', false)) { esc_html_e('Failed To Verify Referrer', 'wp-postratings'); exit(); } if($rate > 0 && $post_id > 0 && check_allowtorate()) { // Check For Bot - $bots_useragent = array('googlebot', 'google', 'msnbot', 'ia_archiver', 'lycos', 'jeeves', 'scooter', 'fast-webcrawler', 'slurp@inktomi', 'turnitinbot', 'technorati', 'yahoo', 'findexa', 'findlinks', 'gaisbo', 'zyborg', 'surveybot', 'bloglines', 'blogsearch', 'ubsub', 'syndic8', 'userland', 'gigabot', 'become.com'); + $bots_useragent = array('googlebot', 'google', 'msnbot', 'ia_archiver', 'lycos', 'jeeves', 'scooter', 'fast-webcrawler', + 'slurp@inktomi', 'turnitinbot', 'technorati', 'yahoo', 'findexa', 'findlinks', 'gaisbo', 'zyborg', + 'surveybot', 'bloglines', 'blogsearch', 'ubsub', 'syndic8', 'userland', 'gigabot', 'become.com'); $useragent = $_SERVER['HTTP_USER_AGENT']; foreach ($bots_useragent as $bot) { if (stristr($useragent, $bot) !== false) { @@ -539,7 +532,6 @@ function process_ratings() { $ratings_max = intval(get_option('postratings_max')); $ratings_custom = intval(get_option('postratings_customrating')); $ratings_value = get_option('postratings_ratingsvalue'); - $post_title = addslashes($post->post_title); $post_ratings = get_post_custom($post_id); $post_ratings_users = ! empty( $post_ratings['ratings_users'] ) ? intval($post_ratings['ratings_users'][0]) : 0; $post_ratings_score = ! empty( $post_ratings['ratings_score'] ) ? intval($post_ratings['ratings_score'][0]) : 0; @@ -556,9 +548,9 @@ function process_ratings() { // Add Log if(!empty($user_identity)) { - $rate_user = addslashes($user_identity); + $rate_user = $user_identity; } elseif(!empty($_COOKIE['comment_author_'.COOKIEHASH])) { - $rate_user = addslashes($_COOKIE['comment_author_'.COOKIEHASH]); + $rate_user = $_COOKIE['comment_author_'.COOKIEHASH]; } else { $rate_user = __('Guest', 'wp-postratings'); } @@ -568,10 +560,25 @@ function process_ratings() { // Only Create Cookie If User Choose Logging Method 1 Or 3 $postratings_logging_method = intval(get_option('postratings_logging_method')); if($postratings_logging_method == 1 || $postratings_logging_method == 3) { - $rate_cookie = setcookie("rated_".$post_id, $ratings_value[$rate-1], apply_filters('wp_postratings_cookie_expiration', (time() + 30000000) ), apply_filters('wp_postratings_cookiepath', SITECOOKIEPATH)); + $rate_cookie = setcookie("rated_" . $post_id, + $ratings_value[$rate-1], + apply_filters('wp_postratings_cookie_expiration', (time() + 30000000) ), + apply_filters('wp_postratings_cookiepath', SITECOOKIEPATH)); } + // Log Ratings No Matter What - $rate_log = $wpdb->query( $wpdb->prepare( "INSERT INTO {$wpdb->ratings} VALUES (%d, %d, %s, %d, %d, %s, %s, %s, %d )", 0, $post_id, $post_title, $ratings_value[$rate-1], current_time('timestamp'), get_ipaddress(), @gethostbyaddr( get_ipaddress() ), $rate_user, $rate_userid ) ); + $rate_log = $wpdb->insert( $wpdb->prefix . "ratings", + array(// 'rating_id' => 0, autoinc + 'rating_postid' => $post_id, + 'rating_posttitle' => $post->post_title, + 'rating_rating' => $ratings_value[$rate-1], + 'rating_timestamp' => current_time('timestamp'), + 'rating_ip' => get_ipaddress(), + 'rating_host' => @gethostbyaddr( get_ipaddress() ), + 'rating_username' => $rate_user, + 'rating_userid' => $rate_userid), + array('%d', '%s', '%d', '%d', '%s', '%s', '%s', '%d') ); + // Allow Other Plugins To Hook When A Post Is Rated do_action('rate_post', $rate_userid, $post_id, $ratings_value[$rate-1]); // Output AJAX Result @@ -618,11 +625,7 @@ function manage_ratings() $postratings_ratingstext[1] = __('Vote Up', 'wp-postratings'); } else { for($i = 0; $i < $postratings_max; $i++) { - if($i > 0) { - $postratings_ratingstext[$i] = sprintf(esc_html__('%s Stars', 'wp-postratings'), number_format_i18n($i+1)); - } else { - $postratings_ratingstext[$i] = sprintf(esc_html__('%s Star', 'wp-postratings'), number_format_i18n($i+1)); - } + $postratings_ratingstext[$i] = esc_html__(sprintf(_n('%s Star', '%s Stars', $i, 'wp-postratings'), number_format_i18n($i+1))); $postratings_ratingsvalue[$i] = $i+1; } } @@ -637,19 +640,27 @@ function manage_ratings() '; + } elseif(file_exists($postratings_path.'/'.$postratings_image.'/rating_start.'.RATINGS_IMG_EXT)) { + $image_start = 'rating_start.'.RATINGS_IMG_EXT.''; + } + + if(is_rtl() && file_exists($postratings_path.'/'.$postratings_image.'/rating_end-rtl.'.RATINGS_IMG_EXT)) { + $image_end = 'rating_end-rtl.'.RATINGS_IMG_EXT.''; + } elseif(file_exists($postratings_path.'/'.$postratings_image.'/rating_end.'.RATINGS_IMG_EXT)) { + $image_end = 'rating_end.'.RATINGS_IMG_EXT.''; + } + for($i = 1; $i <= $postratings_max; $i++) { $postratings_text = stripslashes($postratings_ratingstext[$i-1]); $postratings_value = $postratings_ratingsvalue[$i-1]; if($postratings_value > 0) { $postratings_value = '+'.$postratings_value; } - echo ''."\n"; - echo ''."\n"; - if(is_rtl() && file_exists($postratings_path.'/'.$postratings_image.'/rating_start-rtl.'.RATINGS_IMG_EXT)) { - echo 'rating_start-rtl.'.RATINGS_IMG_EXT.''; - } elseif(file_exists($postratings_path.'/'.$postratings_image.'/rating_start.'.RATINGS_IMG_EXT)) { - echo 'rating_start.'.RATINGS_IMG_EXT.''; - } + echo "\n\n"; + echo $image_start; if($postratings_customrating) { if($postratings_max == 2) { echo 'rating_'.$i.'_on.'.RATINGS_IMG_EXT.''; @@ -663,19 +674,13 @@ function manage_ratings() echo 'rating_on.'.RATINGS_IMG_EXT.''; } } - if(is_rtl() && file_exists($postratings_path.'/'.$postratings_image.'/rating_end-rtl.'.RATINGS_IMG_EXT)) { - echo 'rating_end-rtl.'.RATINGS_IMG_EXT.''; - } elseif(file_exists($postratings_path.'/'.$postratings_image.'/rating_end.'.RATINGS_IMG_EXT)) { - echo 'rating_end.'.RATINGS_IMG_EXT.''; - } - echo ''."\n"; - echo ''."\n"; - echo ''."\n"; - echo ''."\n"; - echo ''."\n"; - echo ''."\n"; - echo ''."\n"; - echo ''."\n"; + echo $image_end; + echo << + + + +EOF; } ?> @@ -809,29 +814,22 @@ function postratings_page_admin_general_stats($content) { ### Function: Add WP-PostRatings Top Most/Highest Stats To WP-Stats Page Options function postratings_page_admin_most_stats($content) { + $content = array(); $stats_display = get_option('stats_display'); $stats_mostlimit = intval(get_option('stats_mostlimit')); - if($stats_display['rated_highest_post'] == 1) { - $content .= '  
'."\n"; - } else { - $content .= '  
'."\n"; - } - if($stats_display['rated_highest_page'] == 1) { - $content .= '  
'."\n"; - } else { - $content .= '  
'."\n"; - } - if($stats_display['rated_most_post'] == 1) { - $content .= '  
'."\n"; - } else { - $content .= '  
'."\n"; - } - if($stats_display['rated_most_page'] == 1) { - $content .= '  
'."\n"; - } else { - $content .= '  
'."\n"; + + foreach(array('rated_highest_post' => _n('%s Highest Rated Post', '%s Highest Rated Posts', $stats_mostlimit, 'wp-postratings'), + 'rated_highest_page' => _n('%s Highest Rated Page', '%s Highest Rated Pages', $stats_mostlimit, 'wp-postratings'), + 'rated_most_post' => _n('%s Most Rated Post', '%s Most Rated Posts', $stats_mostlimit, 'wp-postratings'), + 'rated_most_page' => _n('%s Most Rated Page', '%s Most Rated Pages', $stats_mostlimit, 'wp-postratings')) as $k => $v) { + if($stats_display[$k] == 1) { + $content[] = '' + . '  ' + . '
'."\n"; + } } - return $content; + + return implode('', $content); } @@ -929,66 +927,77 @@ function get_ratings_images($ratings_custom, $ratings_max, $post_rating, $rating } +// $custom: true|false +// $type: one of [on, off, half, half-rtl] +function get_rating_image_url($ratings_image, $type, $i = null /* if custom */) { + if ($i) { + return plugins_url(sprintf("/wp-postratings/images/%s/rating_%d_%s.%s", $ratings_image, $i, $type, RATINGS_IMG_EXT)); + } else { + return plugins_url(sprintf("/wp-postratings/images/%s/rating_%s.%s", $ratings_image, $type, RATINGS_IMG_EXT)); + } +} + ### Function: Gets HTML of rating images for voting function get_ratings_images_vote($post_id, $ratings_custom, $ratings_max, $post_rating, $ratings_image, $image_alt, $insert_half, $ratings_texts) { - $ratings_images = ''; + $ratings_images = array(); + $ratings_image = esc_attr( $ratings_image ); if(is_rtl() && file_exists(WP_PLUGIN_DIR.'/wp-postratings/images/'.$ratings_image.'/rating_start-rtl.'.RATINGS_IMG_EXT)) { - $ratings_images .= ''; + $ratings_images[] = ''; } elseif(file_exists(WP_PLUGIN_DIR.'/wp-postratings/images/'.$ratings_image.'/rating_start.'.RATINGS_IMG_EXT)) { - $ratings_images .= ''; + $ratings_images[] = ''; } - if($ratings_custom) { - for($i=1; $i <= $ratings_max; $i++) { - if (is_rtl() && file_exists(WP_PLUGIN_DIR.'/wp-postratings/images/'.$ratings_image.'/rating_'.$i.'half-rtl.'.RATINGS_IMG_EXT)) { - $use_half_rtl = 1; - } else { - $use_half_rtl = 0; - } - $ratings_text = esc_attr( stripslashes( $ratings_texts[$i-1] ) ); - $ratings_text_js = esc_js( $ratings_text ); - $image_alt = apply_filters( 'wp_postratings_ratings_image_alt', $ratings_text ); - if($i <= $post_rating) { - $ratings_images .= ''.$image_alt.''; - } elseif($i == $insert_half) { - if ($use_half_rtl) { - $ratings_images .= ''.$image_alt.''; - } else { - $ratings_images .= ''.$image_alt.''; - } - } else { - $ratings_images .= ''.$image_alt.''; - } - } + + if (is_rtl() && file_exists(WP_PLUGIN_DIR.'/wp-postratings/images/'.$ratings_image.'/rating_'.$i.'half-rtl.'.RATINGS_IMG_EXT)) { + $use_custom_half_rtl = 1; } else { - if (is_rtl() && file_exists(WP_PLUGIN_DIR.'/wp-postratings/images/'.$ratings_image.'/rating_half-rtl.'.RATINGS_IMG_EXT)) { - $use_half_rtl = 1; - } else { - $use_half_rtl = 0; - } - for($i=1; $i <= $ratings_max; $i++) { - $ratings_text = esc_attr( stripslashes( $ratings_texts[$i-1] ) ); - $ratings_text_js = esc_js( $ratings_text ); - $image_alt = apply_filters( 'wp_postratings_ratings_image_alt', $ratings_text ); - if($i <= $post_rating) { - $ratings_images .= ''.$image_alt.''; - } elseif($i == $insert_half) { - if ($use_half_rtl) { - $ratings_images .= ''.$image_alt.''; - } else { - $ratings_images .= ''.$image_alt.''; - } - } else { - $ratings_images .= ''.$image_alt.''; - } - } + $use_custom_half_rtl = 0; } + if (is_rtl() && file_exists(WP_PLUGIN_DIR.'/wp-postratings/images/'.$ratings_image.'/rating_half-rtl.'.RATINGS_IMG_EXT)) { + $use_half_rtl = 1; + } else { + $use_half_rtl = 0; + } + + + for($i=1; $i <= $ratings_max; $i++) { + $ratings_text = esc_attr( stripslashes( $ratings_texts[$i-1] ) ) ; + $image_alt = esc_attr( apply_filters( 'wp_postratings_ratings_image_alt', $ratings_text ) ); + + $rating_attr = array( + 'id' => "rating_" . $post_id . "_" . $i, + 'alt' => $image_alt, + 'title' => $image_alt, + 'onmouseover' => esc_js( sprintf( "current_rating(%d, %d, \"%s\");", $post_id, $i, $ratings_text) ), + 'onclick' => sprintf( "rate_post(%d, %d);", $post_id, $i), + 'onkeypress' => sprintf( "rate_post(%d, %d);", $post_id, $i), + 'style' => "cursor:pointer; border:0px;" + ); + + if($ratings_custom) { + $rating_attr += array( + 'src' => get_rating_image_url($ratings_image, $i <= $post_rating ? 'on' : $i == $insert_half ? $use_custom_half_rtl ? 'half-rtl' : 'half' : 'off', $i), + 'onmouseout' => sprintf("ratings_off(%d, %d, %d, %d);", $post_id, $post_rating, $insert_half, $use_custom_half_rtl), + ); + } else { + $rating_attr += array( + 'src' => get_rating_image_url($ratings_image, $i <= $post_rating ? 'on' : $i == $insert_half ? $use_half_rtl ? 'half-rtl' : 'half' : 'off', NULL), + 'onmouseout' => sprintf("ratings_off(%d, %d, %d, %d);", $post_id, $post_rating, $insert_half, $use_half_rtl), + ); + } + + $ratings_images[] = ''; + } + + if(is_rtl() && file_exists(WP_PLUGIN_DIR.'/wp-postratings/images/'.$ratings_image.'/rating_end-rtl.'.RATINGS_IMG_EXT)) { - $ratings_images .= ''; - } elseif(file_exists(WP_PLUGIN_DIR.'/wp-postratings/images/'.$ratings_image.'/rating_end.'.RATINGS_IMG_EXT)) { - $ratings_images .= ''; + $ratings_images[] = ''; } - return $ratings_images; + elseif(file_exists(WP_PLUGIN_DIR.'/wp-postratings/images/'.$ratings_image.'/rating_end.'.RATINGS_IMG_EXT)) { + $ratings_images[] = ''; + } + + return implode('', $ratings_images); } @@ -1111,13 +1120,14 @@ function expand_ratings_template($template, $post_data, $post_ratings_data = nul $post_ratings_images = apply_filters( 'wp_postratings_ratings_images_vote', $get_ratings_images_vote, $post_id, $post_ratings, $ratings_max ); $value = str_replace( "%RATINGS_IMAGES_VOTE%", $post_ratings_images, $value ); } - $value = str_replace("%RATINGS_ALT_TEXT%", $post_ratings_alt_text, $value); - $value = str_replace("%RATINGS_TEXT%", $post_ratings_text, $value); - $value = str_replace("%RATINGS_MAX%", number_format_i18n($ratings_max), $value); - $value = str_replace("%RATINGS_SCORE%", $post_ratings_score, $value); - $value = str_replace("%RATINGS_AVERAGE%", number_format_i18n($post_ratings_average, 2), $value); - $value = str_replace("%RATINGS_PERCENTAGE%", number_format_i18n($post_ratings_percentage, 2), $value); - $value = str_replace("%RATINGS_USERS%", number_format_i18n($post_ratings_users), $value); + + $search1 = array("%RATINGS_ALT_TEXT%", "%RATINGS_TEXT%", "%RATINGS_MAX%", "%RATINGS_SCORE%"); + $replac1 = array($post_ratings_alt_text, $post_ratings_text, number_format_i18n($ratings_max), $post_ratings_score); + $value = str_replace($search1, $replac1, $value); + + $search2 = array("%RATINGS_AVERAGE%", "%RATINGS_PERCENTAGE%", "%RATINGS_USERS%"); + $replac2 = array(number_format_i18n($post_ratings_average, 2), number_format_i18n($post_ratings_percentage, 2), number_format_i18n($post_ratings_users)); + $value = str_replace($search2, $replac2, $value); // Post Template Variables $post_link = get_permalink($post_data); @@ -1125,32 +1135,29 @@ function expand_ratings_template($template, $post_data, $post_ratings_data = nul if ($max_post_title_chars > 0) { $post_title = snippet_text($post_title, $max_post_title_chars); } - $value = str_replace("%POST_ID%", $post_id, $value); - $value = str_replace("%POST_TITLE%", $post_title, $value); - $value = str_replace("%POST_URL%", $post_link, $value); + $value = str_replace(array("%POST_ID%", "%POST_TITLE%", "%POST_URL%"), + array($post_id, $post_title, $post_link), + $value); - if (strpos($template, '%POST_EXCERPT%') !== false) { + if (preg_match('/%POST_(EXCERPT|CONTENT|THUMBNAIL)%/', $template)) { if (get_the_ID() != $post_id) { $post = &get_post($post_id); } - $post_excerpt = ratings_post_excerpt($post_id, $post->post_excerpt, $post->post_content, $post->post_password); - $value = str_replace("%POST_EXCERPT%", $post_excerpt, $value); - } - if (strpos($template, '%POST_CONTENT%') !== false) { - if (get_the_ID() != $post_id) { - $post = &get_post($post_id); + + if (strpos($template, '%POST_EXCERPT%') !== false) { + $post_excerpt = ratings_post_excerpt($post_id, $post->post_excerpt, $post->post_content, $post->post_password); + $value = str_replace("%POST_EXCERPT%", $post_excerpt, $value); } - $value = str_replace("%POST_CONTENT%", get_the_content(), $value); - } - if (strpos($template, '%POST_THUMBNAIL%') !== false) { - if (get_the_ID() != $post_id) { - $post = &get_post($post_id); + if (strpos($template, '%POST_CONTENT%') !== false) { + $value = str_replace("%POST_CONTENT%", get_the_content(), $value); + } + if (strpos($template, '%POST_THUMBNAIL%') !== false) { + $value = str_replace( '%POST_THUMBNAIL%', get_the_post_thumbnail( $post, 'thumbnail' ), $value ); } - $value = str_replace( '%POST_THUMBNAIL%', get_the_post_thumbnail( $post, 'thumbnail' ), $value ); } // Google Rich Snippet - $google_structured_data = ''; + $google_structured_data = ''; $ratings_options['richsnippet'] = isset( $ratings_options['richsnippet'] ) ? $ratings_options['richsnippet'] : 1; if( $ratings_options['richsnippet'] && is_singular() && $is_main_loop ) { $itemtype = apply_filters( 'wp_postratings_schema_itemtype', 'itemscope itemtype="http://schema.org/Article"' ); @@ -1158,24 +1165,25 @@ function expand_ratings_template($template, $post_data, $post_ratings_data = nul if( empty( $post_excerpt ) ) { $post_excerpt = ratings_post_excerpt( $post_id, $post->post_excerpt, $post->post_content, $post->post_password ); } - $post_meta = ''; - $post_meta .= ''; - $post_meta .= ''; - $post_meta .= ''; - $post_meta .= ''; - $post_meta .= ''; - $post_meta .= ''; + $post_meta = '' + . '' + . '' + . '' + . '' + . '' + . ''; + // Image - if( has_post_thumbnail() ) { - $thumbnail = wp_get_attachment_image_src( get_post_thumbnail_id( null ) ); - if( ! empty( $thumbnail ) ) { - $post_meta .= '
'; - $post_meta .= ''; - $post_meta .= ''; - $post_meta .= ''; - $post_meta .= '
'; - } + if( has_post_thumbnail() && ( $thumbnail = wp_get_attachment_image_src( get_post_thumbnail_id( null ) ) ) ) { + $post_meta .= << + + + + +EOF; } + // Publisher $site_logo = ''; if ( function_exists( 'the_custom_logo' ) ) { @@ -1185,7 +1193,7 @@ function expand_ratings_template($template, $post_data, $post_ratings_data = nul $site_logo = $custom_logo[0]; } } - if( empty( $site_logo ) ) { + if( ! $site_logo ) { if( has_header_image() ) { $header_image = get_header_image(); if( ! empty( $header_image ) ) { @@ -1193,22 +1201,28 @@ function expand_ratings_template($template, $post_data, $post_ratings_data = nul } } } + $site_logo = apply_filters( 'wp_postratings_site_logo', $site_logo ); - $post_meta .= '
'; - $post_meta .= ''; - $post_meta .= '
'; - $post_meta .= ''; - $post_meta .= '
'; - $post_meta .= '
'; + $site_name = get_bloginfo( 'name' ); + $post_meta .= << + +
+ +
+ +EOF; $ratings_meta = ''; if( $post_ratings_average > 0 ) { - $ratings_meta .= '
'; - $ratings_meta .= ''; - $ratings_meta .= ''; - $ratings_meta .= ''; - $ratings_meta .= ''; - $ratings_meta .= '
'; + $ratings_meta = << + + + + + +EOF; } $google_structured_data = apply_filters( 'wp_postratings_google_structured_data', ( empty( $itemtype ) ? $ratings_meta : ( $post_meta . $ratings_meta ) ) ); From 3b6b651efcaf7673bc8d04ff763c92d4be9264fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Droz?= Date: Wed, 5 Jul 2017 21:10:04 -0300 Subject: [PATCH 03/32] use data-* element to pass textual data --- js/postratings-js.dev.js | 5 ++--- wp-postratings.php | 5 ++++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/js/postratings-js.dev.js b/js/postratings-js.dev.js index b07e542..a9b3277 100644 --- a/js/postratings-js.dev.js +++ b/js/postratings-js.dev.js @@ -38,18 +38,17 @@ if(ratingsL10n.custom) { } // When User Mouse Over Ratings -function current_rating(post_id, post_rating, rating_text) { +function current_rating(post_id, post_rating) { if(!is_being_rated) { if(ratingsL10n.custom && ratingsL10n.max == 2) { document.getElementById('rating_' + post_id + '_' + post_rating).src = ratings_mouseover_image[i].src; } else { for(var i = 1; i <= post_rating; i++) { - console.log("#" + 'rating_' + post_id + '_' + i + ' = ' + ratings_mouseover_image.src); document.getElementById('rating_' + post_id + '_' + i).src = ratingsL10n.custom ? ratings_mouseover_image[i].src : ratings_mouseover_image.src; } } if(jQuery('#ratings_' + post_id + '_text').length) { - jQuery('#ratings_' + post_id + '_text').html(rating_text).show(); + jQuery('#ratings_' + post_id + '_text').html(jQuery('#rating_' + post_id + '_' + post_rating).data('ratingsText')).show(); } } } diff --git a/wp-postratings.php b/wp-postratings.php index 0a45df3..c25892e 100644 --- a/wp-postratings.php +++ b/wp-postratings.php @@ -968,7 +968,10 @@ function get_ratings_images_vote($post_id, $ratings_custom, $ratings_max, $post_ 'id' => "rating_" . $post_id . "_" . $i, 'alt' => $image_alt, 'title' => $image_alt, - 'onmouseover' => esc_js( sprintf( "current_rating(%d, %d, \"%s\");", $post_id, $i, $ratings_text) ), + 'data-id' => $post_id, + 'data-votes' => $i, + 'data-ratings-text' => $ratings_text, + 'onmouseover' => esc_js( sprintf( "current_rating(%d, %d);", $post_id, $i) ), 'onclick' => sprintf( "rate_post(%d, %d);", $post_id, $i), 'onkeypress' => sprintf( "rate_post(%d, %d);", $post_id, $i), 'style' => "cursor:pointer; border:0px;" From d5495ca42f70951b126620b87d5358fbd8727742 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Droz?= Date: Wed, 5 Jul 2017 23:27:20 -0300 Subject: [PATCH 04/32] split process_ratings() so that it could be reused from Ajax but also from others means (regular POST/hooks/...) --- wp-postratings.php | 189 ++++++++++++++++++++++++--------------------- 1 file changed, 102 insertions(+), 87 deletions(-) diff --git a/wp-postratings.php b/wp-postratings.php index c25892e..94af6b7 100644 --- a/wp-postratings.php +++ b/wp-postratings.php @@ -494,12 +494,24 @@ function delete_ratings_fields($post_ID) { } -### Function: Process Ratings -add_action('wp_ajax_postratings', 'process_ratings'); -add_action('wp_ajax_nopriv_postratings', 'process_ratings'); -function process_ratings() { - global $wpdb, $user_identity, $user_ID; +// Check For Bot +function is_bot($useragent) { + $bots_useragent = array('googlebot', 'google', 'msnbot', 'ia_archiver', 'lycos', 'jeeves', 'scooter', 'fast-webcrawler', + 'slurp@inktomi', 'turnitinbot', 'technorati', 'yahoo', 'findexa', 'findlinks', 'gaisbo', 'zyborg', + 'surveybot', 'bloglines', 'blogsearch', 'ubsub', 'syndic8', 'userland', 'gigabot', 'become.com'); + foreach ($bots_useragent as $bot) { + if (stristr($useragent, $bot) !== false) { + return true; + } + } + return false; +} + +### Function: Process Ratings +add_action('wp_ajax_postratings', 'process_ratings_from_ajax'); +add_action('wp_ajax_nopriv_postratings', 'process_ratings_from_ajax'); +function process_ratings_from_ajax() { if(isset($_REQUEST['action']) && $_REQUEST['action'] == 'postratings') { $rate = intval($_REQUEST['rate']); $post_id = intval($_REQUEST['pid']); @@ -510,92 +522,95 @@ function process_ratings() { exit(); } - if($rate > 0 && $post_id > 0 && check_allowtorate()) { - // Check For Bot - $bots_useragent = array('googlebot', 'google', 'msnbot', 'ia_archiver', 'lycos', 'jeeves', 'scooter', 'fast-webcrawler', - 'slurp@inktomi', 'turnitinbot', 'technorati', 'yahoo', 'findexa', 'findlinks', 'gaisbo', 'zyborg', - 'surveybot', 'bloglines', 'blogsearch', 'ubsub', 'syndic8', 'userland', 'gigabot', 'become.com'); - $useragent = $_SERVER['HTTP_USER_AGENT']; - foreach ($bots_useragent as $bot) { - if (stristr($useragent, $bot) !== false) { - return; - } - } - header( 'Content-Type: text/html; charset=' . get_option( 'blog_charset' ) ); - $rated = check_rated($post_id); - // Check Whether Post Has Been Rated By User - if(!$rated) { - // Check Whether Is There A Valid Post - $post = get_post($post_id); - // If Valid Post Then We Rate It - if($post && !wp_is_post_revision($post)) { - $ratings_max = intval(get_option('postratings_max')); - $ratings_custom = intval(get_option('postratings_customrating')); - $ratings_value = get_option('postratings_ratingsvalue'); - $post_ratings = get_post_custom($post_id); - $post_ratings_users = ! empty( $post_ratings['ratings_users'] ) ? intval($post_ratings['ratings_users'][0]) : 0; - $post_ratings_score = ! empty( $post_ratings['ratings_score'] ) ? intval($post_ratings['ratings_score'][0]) : 0; - // Check For Ratings Lesser Than 1 And Greater Than $ratings_max - if($rate < 1 || $rate > $ratings_max) { - $rate = 0; - } - $post_ratings_users = ($post_ratings_users+1); - $post_ratings_score = ($post_ratings_score+intval($ratings_value[$rate-1])); - $post_ratings_average = round($post_ratings_score/$post_ratings_users, 2); - update_post_meta($post_id, 'ratings_users', $post_ratings_users); - update_post_meta($post_id, 'ratings_score', $post_ratings_score); - update_post_meta($post_id, 'ratings_average', $post_ratings_average); - - // Add Log - if(!empty($user_identity)) { - $rate_user = $user_identity; - } elseif(!empty($_COOKIE['comment_author_'.COOKIEHASH])) { - $rate_user = $_COOKIE['comment_author_'.COOKIEHASH]; - } else { - $rate_user = __('Guest', 'wp-postratings'); - } - $rate_user = apply_filters( 'wp_postratings_process_ratings_user', $rate_user ); - $rate_userid = apply_filters( 'wp_postratings_process_ratings_userid', intval( $user_ID ) ); - - // Only Create Cookie If User Choose Logging Method 1 Or 3 - $postratings_logging_method = intval(get_option('postratings_logging_method')); - if($postratings_logging_method == 1 || $postratings_logging_method == 3) { - $rate_cookie = setcookie("rated_" . $post_id, - $ratings_value[$rate-1], - apply_filters('wp_postratings_cookie_expiration', (time() + 30000000) ), - apply_filters('wp_postratings_cookiepath', SITECOOKIEPATH)); - } + if (is_bot($_SERVER['HTTP_USER_AGENT'])) { + esc_html_e('Bots refused', 'wp-postratings'); + exit(); + } - // Log Ratings No Matter What - $rate_log = $wpdb->insert( $wpdb->prefix . "ratings", - array(// 'rating_id' => 0, autoinc - 'rating_postid' => $post_id, - 'rating_posttitle' => $post->post_title, - 'rating_rating' => $ratings_value[$rate-1], - 'rating_timestamp' => current_time('timestamp'), - 'rating_ip' => get_ipaddress(), - 'rating_host' => @gethostbyaddr( get_ipaddress() ), - 'rating_username' => $rate_user, - 'rating_userid' => $rate_userid), - array('%d', '%s', '%d', '%d', '%s', '%s', '%s', '%d') ); - - // Allow Other Plugins To Hook When A Post Is Rated - do_action('rate_post', $rate_userid, $post_id, $ratings_value[$rate-1]); - // Output AJAX Result - echo the_ratings_results($post_id, $post_ratings_users, $post_ratings_score, $post_ratings_average); - exit(); - } else { - printf(esc_html__('Invalid Post ID (#%s).', 'wp-postratings'), $post_id); - exit(); - } // End if($post) - } else { - printf(esc_html__('You Had Already Rated This Post. Post ID #%s.', 'wp-postratings'), $post_id); - exit(); - }// End if(!$rated) - } // End if($rate && $post_id && check_allowtorate()) + + header( 'Content-Type: text/html; charset=' . get_option( 'blog_charset' ) ); + $ret = process_ratings($post_id, $rate); + if (! $ret) exit(); } // End if(isset($_REQUEST['action']) && $_REQUEST['action'] == 'postratings') } +// integer $last_id: in/out, if given, fill it with the rate ID inserted inside the DB +function process_ratings($post_id, $rate, &$last_id = NULL) { + global $wpdb, $user_identity, $user_ID; + + if($rate > 0 && $post_id > 0 && check_allowtorate()) { + // Check Whether Post Has Been Rated By User + if (check_rated($post_id)) { + printf(esc_html__('You Had Already Rated This Post. Post ID #%s.', 'wp-postratings'), $post_id); + return FALSE; + } + + // Check Whether Is There A Valid Post + $post = get_post($post_id); + if (! $post || wp_is_post_revision($post)) { + printf(esc_html__('Invalid Post ID (#%s).', 'wp-postratings'), $post_id); + return FALSE; + } + + // If Valid Post Then We Rate It + $ratings_max = intval(get_option('postratings_max')); + $ratings_custom = intval(get_option('postratings_customrating')); + $ratings_value = get_option('postratings_ratingsvalue'); + $post_ratings = get_post_custom($post_id); + $post_ratings_users = ! empty( $post_ratings['ratings_users'] ) ? intval($post_ratings['ratings_users'][0]) : 0; + $post_ratings_score = ! empty( $post_ratings['ratings_score'] ) ? intval($post_ratings['ratings_score'][0]) : 0; + // Check For Ratings Lesser Than 1 And Greater Than $ratings_max + if($rate < 1 || $rate > $ratings_max) { + $rate = 0; + } + $post_ratings_users = ($post_ratings_users+1); + $post_ratings_score = ($post_ratings_score+intval($ratings_value[$rate-1])); + $post_ratings_average = round($post_ratings_score/$post_ratings_users, 2); + update_post_meta($post_id, 'ratings_users', $post_ratings_users); + update_post_meta($post_id, 'ratings_score', $post_ratings_score); + update_post_meta($post_id, 'ratings_average', $post_ratings_average); + + // Add Log + if(!empty($user_identity)) { + $rate_user = $user_identity; + } elseif(!empty($_COOKIE['comment_author_'.COOKIEHASH])) { + $rate_user = $_COOKIE['comment_author_'.COOKIEHASH]; + } else { + $rate_user = __('Guest', 'wp-postratings'); + } + $rate_user = apply_filters( 'wp_postratings_process_ratings_user', $rate_user ); + $rate_userid = apply_filters( 'wp_postratings_process_ratings_userid', intval( $user_ID ) ); + + // Only Create Cookie If User Choose Logging Method 1 Or 3 + $postratings_logging_method = intval(get_option('postratings_logging_method')); + if($postratings_logging_method == 1 || $postratings_logging_method == 3) { + $rate_cookie = setcookie("rated_" . $post_id, + $ratings_value[$rate-1], + apply_filters('wp_postratings_cookie_expiration', (time() + 30000000) ), + apply_filters('wp_postratings_cookiepath', SITECOOKIEPATH)); + } + + // Log Ratings No Matter What + $rate_log = $wpdb->insert( $wpdb->prefix . "ratings", + array(// 'rating_id' => 0, autoinc + 'rating_postid' => $post_id, + 'rating_posttitle' => $post->post_title, + 'rating_rating' => $ratings_value[$rate-1], + 'rating_timestamp' => current_time('timestamp'), + 'rating_ip' => get_ipaddress(), + 'rating_host' => @gethostbyaddr( get_ipaddress() ), + 'rating_username' => $rate_user, + 'rating_userid' => $rate_userid), + array('%d', '%s', '%d', '%d', '%s', '%s', '%s', '%d') ); + + $last_id = $wpdb->insert_id; + // Allow Other Plugins To Hook When A Post Is Rated + do_action('rate_post', $rate_userid, $post_id, $ratings_value[$rate-1]); + // Output AJAX Result + return the_ratings_results($post_id, $post_ratings_users, $post_ratings_score, $post_ratings_average); + } // End if($rate && $post_id && check_allowtorate()) +} + ### Function: Process Ratings add_action('wp_ajax_postratings-admin', 'manage_ratings'); From 526abab7c35f887ef767635ae4313f5c7a23b301 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Droz?= Date: Wed, 5 Jul 2017 23:57:52 -0300 Subject: [PATCH 05/32] bind voting to comment submission. If the option is enabled, voting will NOT be submitted through Ajax. Instead one simply have to show the voting stars near the comment form submission, like with ``` // Notice the 4th arg = FALSE (== no Ajax submission) function bind_rate_comments() { the_ratings('div', 0, true, false); } add_action( 'comment_form' , 'bind_rate_comments' , 5 ); ``` Voting will then happen in the comment insertion hook. --- includes/postratings-scripts.php | 4 +-- js/postratings-js.dev.js | 32 +++++++++++++++++- postratings-options.php | 18 ++++++++++ uninstall.php | 1 + wp-postratings.php | 56 ++++++++++++++++++++++++++++---- 5 files changed, 101 insertions(+), 10 deletions(-) diff --git a/includes/postratings-scripts.php b/includes/postratings-scripts.php index 8218df8..1310760 100644 --- a/includes/postratings-scripts.php +++ b/includes/postratings-scripts.php @@ -61,12 +61,12 @@ function ratings_scripts_admin($hook_suffix) { } // this need to be triggered manually -function ratings_script_config() { +function ratings_script_config($ajax = TRUE) { $postratings_ajax_style = get_option( 'postratings_ajax_style' ); wp_localize_script('wp-postratings', 'ratingsL10n', array( 'plugin_url' => plugins_url( 'wp-postratings' ), - 'ajax_url' => admin_url('admin-ajax.php'), + 'ajax_url' => $ajax ? admin_url('admin-ajax.php') : FALSE, 'text_wait' => __('Please rate only 1 item at a time.', 'wp-postratings'), 'image' => get_option( 'postratings_image' ), 'image_ext' => RATINGS_IMG_EXT, diff --git a/js/postratings-js.dev.js b/js/postratings-js.dev.js index a9b3277..16cf652 100644 --- a/js/postratings-js.dev.js +++ b/js/postratings-js.dev.js @@ -39,6 +39,14 @@ if(ratingsL10n.custom) { // When User Mouse Over Ratings function current_rating(post_id, post_rating) { + if (! ratingsL10n.ajax_url) { + var element = $j('input[name="wp_postrating_form_value_' + post_id + '"]'); + // mouseout, but a value was click/selected in order to be later POSTed: do nothing + if (parseInt($j(element).val())) { + return; + } + } + if(!is_being_rated) { if(ratingsL10n.custom && ratingsL10n.max == 2) { document.getElementById('rating_' + post_id + '_' + post_rating).src = ratings_mouseover_image[i].src; @@ -55,10 +63,20 @@ function current_rating(post_id, post_rating) { // When User Mouse Out Ratings function ratings_off(post_id, rating_score, insert_half, half_rtl) { + var element; + + if (! ratingsL10n.ajax_url) { + element = $j('input[name="wp_postrating_form_value_' + post_id + '"]'); + // mouseout, but a value was click/selected in order to be later POSTed: do nothing + if (parseInt($j(element).val())) { + return; + } + } + if(!is_being_rated) { var baseimg = ratingsL10n.plugin_url + '/images/' + ratingsL10n.image + '/rating' ; for(var i = 1; i <= ratingsL10n.max; i++) { - var element = document.getElementById('rating_' + post_id + '_' + i); + element = document.getElementById('rating_' + post_id + '_' + i); if(i <= rating_score) { element.src = baseimg + (ratingsL10n.custom ? '_' + i : '') + '_on.' + ratingsL10n.image_ext; } else if(i == insert_half) { @@ -96,6 +114,18 @@ function rate_post_success(post_id, data) { // Process Post Ratings function rate_post(post_id, post_rating) { var post_ratings_el = $j('#post-ratings-' + post_id); + if (! ratingsL10n.ajax_url) { + var value_holder = $j('input[name="wp_postrating_form_value_' + post_id + '"]'); + var curval = $j(value_holder).val(); + $j(value_holder).val(null); + $j('#rating_' + post_id + '_' + curval).trigger('mouseout'); + if (curval != post_rating) { + $j('#rating_' + post_id + '_' + post_rating).trigger('mouseover'); + $j(value_holder).val(post_rating); + } + return; + } + if(!is_being_rated) { var post_ratings_nonce = $j(post_ratings_el).data('nonce'); if(typeof post_ratings_nonce == 'undefined' || post_ratings_nonce == null) diff --git a/postratings-options.php b/postratings-options.php index 07db9c4..a71b1b0 100644 --- a/postratings-options.php +++ b/postratings-options.php @@ -60,6 +60,7 @@ $postratings_ajax_style = array('loading' => intval($_POST['postratings_ajax_style_loading']), 'fading' => intval($_POST['postratings_ajax_style_fading'])); $postratings_logging_method = intval($_POST['postratings_logging_method']); + $postratings_onlyifcomment = intval($_POST['postratings_onlyifcomment']); $postratings_allowtorate = intval($_POST['postratings_allowtorate']); $update_ratings_queries = array(); $update_ratings_text = array(); @@ -77,6 +78,7 @@ $update_ratings_queries[] = update_option('postratings_ratingsvalue', $postratings_ratingsvalue); $update_ratings_queries[] = update_option('postratings_ajax_style', $postratings_ajax_style); $update_ratings_queries[] = update_option('postratings_logging_method', $postratings_logging_method); + $update_ratings_queries[] = update_option('postratings_onlyifcomment', $postratings_onlyifcomment); $update_ratings_queries[] = update_option('postratings_allowtorate', $postratings_allowtorate); $update_ratings_queries[] = update_option('postratings_options', $postratings_options); $update_ratings_text[] = __('Custom Rating', 'wp-postratings'); @@ -384,6 +386,22 @@ function set_custom(custom, max) { + +

+ + + + + + + +
+ +
+

diff --git a/uninstall.php b/uninstall.php index 88d30fc..2b3cbca 100644 --- a/uninstall.php +++ b/uninstall.php @@ -12,6 +12,7 @@ , 'postratings_template_text' , 'postratings_template_none' , 'postratings_logging_method' + , 'postratings_onlyifcomment' , 'postratings_allowtorate' , 'postratings_ratingstext' , 'postratings_template_highestrated' diff --git a/wp-postratings.php b/wp-postratings.php index 94af6b7..50feb7d 100644 --- a/wp-postratings.php +++ b/wp-postratings.php @@ -75,13 +75,13 @@ function postratings_init() { } ### Function: Display The Rating For The Post -function the_ratings($start_tag = 'div', $custom_id = 0, $display = true /* obsolete */) { - if ($display) echo get_the_ratings($start_tag, $custom_id); - else return get_the_ratings($start_tag, $custom_id); +function the_ratings($start_tag = 'div', $custom_id = 0, $display = true /* obsolete */, $ajax = true) { + if ($display) echo get_the_ratings($start_tag, $custom_id, $ajax); + else return get_the_ratings($start_tag, $custom_id, $ajax); } ### Function: Get The Rating For The Post -function get_the_ratings($start_tag = 'div', $custom_id = 0) { +function get_the_ratings($start_tag = 'div', $custom_id = 0, $ajax) { global $id; // Allow Custom ID if(intval($custom_id) > 0) { @@ -129,10 +129,11 @@ function get_the_ratings($start_tag = 'div', $custom_id = 0) { return "<$start_tag $attributes>".the_ratings_results($ratings_id, 0, 0, 0, 1).''.$loading; // If User Has Not Voted } else { - ratings_script_config(); + ratings_script_config($ajax); $html_string = ''; - $html_string += '' . "\n"; - + if (! $ajax) { + $html_string .= '' . "\n"; + } return $html_string . "<$start_tag $attributes data-nonce=\"".wp_create_nonce('postratings_'.$ratings_id.'-nonce')."\">".the_ratings_vote($ratings_id).''.$loading; } } @@ -1248,3 +1249,44 @@ function expand_ratings_template($template, $post_data, $post_ratings_data = nul return apply_filters( 'expand_ratings_template', ( $value . $google_structured_data ) ); } + +add_filter( 'wp_insert_comment', 'process_ratings_from_comment' ); +function process_ratings_from_comment($comment_id) { + $post_id = intval($_POST['comment_post_ID']); + $rate = intval($_POST["wp_postrating_form_value_$post_id"]); + if (! $post_id || ! $rate) { + // ignored (could be simply a second comment while missing a second vote) + return; + } + + $allow_to_vote_with_comment = intval(get_option('postratings_onlyifcomment')); + if (! $allow_to_vote_with_comment) { + return; + } + + $rate_id = 0; + process_ratings($post_id, $rate, $rate_id); + if ($rate_id) { + add_comment_meta( $comment_id, 'postratings_id', $rate_id ); + } +} + +add_filter( 'comments_array', 'show_rating_in_comment' ); +function show_rating_in_comment($comments) { + if( ! count( $comments ) ) return; + global $wpdb; + + foreach( $comments as $comment ) { + $rate_id = get_comment_meta($comment->comment_ID, 'postratings_id', true); + if (intval($rate_id)) { + $rate = $wpdb->get_var( $wpdb->prepare( "SELECT rating_rating FROM {$wpdb->ratings} WHERE rating_id = %d", intval($rate_id)) ); + if ($rate) { + $comment->comment_content .= '

' + . esc_html(sprintf(__('Rated %d', 'wp-postratings'), $rate)) + . '

'; + } + } + } + + return $comments; +} From 8f555c7aba863d1c24c3996d4d1791cf086d07e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Droz?= Date: Thu, 6 Jul 2017 14:54:16 -0300 Subject: [PATCH 06/32] comment+vote: show the vote in a new column in the comment-manage table --- wp-postratings.php | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/wp-postratings.php b/wp-postratings.php index 50feb7d..60338c9 100644 --- a/wp-postratings.php +++ b/wp-postratings.php @@ -1290,3 +1290,25 @@ function show_rating_in_comment($comments) { return $comments; } +add_filter( 'manage_edit-comments_columns', 'comment_has_vote' ); +function comment_has_vote( $columns ) { + $columns['comment-vote'] = __( 'Vote', 'wp-postratings' ); + return $columns; +} + + +add_filter( 'manage_comments_custom_column', 'recent_comment_has_vote', 20, 2 ); +function recent_comment_has_vote( $column_name, $comment_id ) { + if( 'comment-vote' != strtolower( $column_name ) ) return; + if ( ( $rate_id = get_comment_meta( $comment_id, 'postratings_id', true ) ) ) { + if (intval($rate_id)) { + global $wpdb; + $rate = $wpdb->get_var( $wpdb->prepare( "SELECT rating_rating FROM {$wpdb->ratings} WHERE rating_id = %d", intval($rate_id)) ); + if ($rate) { + printf(__('Rated at %d', 'wp-postratings'), $rate); + } + } + } + + return $options; +} From f93d6b171c63987a1e420c08f0bd2099be6275fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Droz?= Date: Sat, 8 Jul 2017 01:57:37 -0300 Subject: [PATCH 07/32] comment+vote: don't forcefully output the error (useful if call from the REST API). Less nested if's and more detailled error strings --- wp-postratings.php | 166 ++++++++++++++++++++++++++------------------- 1 file changed, 95 insertions(+), 71 deletions(-) diff --git a/wp-postratings.php b/wp-postratings.php index 60338c9..cb2f2ae 100644 --- a/wp-postratings.php +++ b/wp-postratings.php @@ -530,86 +530,110 @@ function process_ratings_from_ajax() { header( 'Content-Type: text/html; charset=' . get_option( 'blog_charset' ) ); - $ret = process_ratings($post_id, $rate); - if (! $ret) exit(); + + $last_id = 0; $last_error = ''; + $ret = process_ratings($post_id, $rate, $last_id, $last_error); + if (! $ret) { + printf($last_error); + exit(); + } } // End if(isset($_REQUEST['action']) && $_REQUEST['action'] == 'postratings') } // integer $last_id: in/out, if given, fill it with the rate ID inserted inside the DB -function process_ratings($post_id, $rate, &$last_id = NULL) { +function process_ratings($post_id, $rate, &$last_id = NULL, &$last_error = NULL) { global $wpdb, $user_identity, $user_ID; - if($rate > 0 && $post_id > 0 && check_allowtorate()) { - // Check Whether Post Has Been Rated By User - if (check_rated($post_id)) { - printf(esc_html__('You Had Already Rated This Post. Post ID #%s.', 'wp-postratings'), $post_id); - return FALSE; - } + if($rate <= 0) { + if (! is_null($last_error)) + $last_error = esc_html__('Invalid rate value.', 'wp-postratings'); + return FALSE; + } - // Check Whether Is There A Valid Post - $post = get_post($post_id); - if (! $post || wp_is_post_revision($post)) { - printf(esc_html__('Invalid Post ID (#%s).', 'wp-postratings'), $post_id); - return FALSE; - } + if (! $post_id) { + if (! is_null($last_error)) + $last_error = sprintf(esc_html__('Invalid Post ID #%d.', 'wp-postratings'), $post_id); + return FALSE; + } - // If Valid Post Then We Rate It - $ratings_max = intval(get_option('postratings_max')); - $ratings_custom = intval(get_option('postratings_customrating')); - $ratings_value = get_option('postratings_ratingsvalue'); - $post_ratings = get_post_custom($post_id); - $post_ratings_users = ! empty( $post_ratings['ratings_users'] ) ? intval($post_ratings['ratings_users'][0]) : 0; - $post_ratings_score = ! empty( $post_ratings['ratings_score'] ) ? intval($post_ratings['ratings_score'][0]) : 0; - // Check For Ratings Lesser Than 1 And Greater Than $ratings_max - if($rate < 1 || $rate > $ratings_max) { - $rate = 0; - } - $post_ratings_users = ($post_ratings_users+1); - $post_ratings_score = ($post_ratings_score+intval($ratings_value[$rate-1])); - $post_ratings_average = round($post_ratings_score/$post_ratings_users, 2); - update_post_meta($post_id, 'ratings_users', $post_ratings_users); - update_post_meta($post_id, 'ratings_score', $post_ratings_score); - update_post_meta($post_id, 'ratings_average', $post_ratings_average); - - // Add Log - if(!empty($user_identity)) { - $rate_user = $user_identity; - } elseif(!empty($_COOKIE['comment_author_'.COOKIEHASH])) { - $rate_user = $_COOKIE['comment_author_'.COOKIEHASH]; - } else { - $rate_user = __('Guest', 'wp-postratings'); - } - $rate_user = apply_filters( 'wp_postratings_process_ratings_user', $rate_user ); - $rate_userid = apply_filters( 'wp_postratings_process_ratings_userid', intval( $user_ID ) ); - - // Only Create Cookie If User Choose Logging Method 1 Or 3 - $postratings_logging_method = intval(get_option('postratings_logging_method')); - if($postratings_logging_method == 1 || $postratings_logging_method == 3) { - $rate_cookie = setcookie("rated_" . $post_id, - $ratings_value[$rate-1], - apply_filters('wp_postratings_cookie_expiration', (time() + 30000000) ), - apply_filters('wp_postratings_cookiepath', SITECOOKIEPATH)); - } + if (! check_allowtorate()) { + if (! is_null($last_error)) + $last_error = esc_html__('Voting forbidden, check policy.', 'wp-postratings'); + return FALSE; + } + + // Check Whether Post Has Been Rated By User + if (check_rated($post_id)) { + if (! is_null($last_error)) + $last_error = sprintf(esc_html__('You already rated post #%d.', 'wp-postratings'), $post_id); + return FALSE; + } + + // Check Whether Is There A Valid Post + $post = get_post($post_id); + if (! $post || wp_is_post_revision($post)) { + if (! is_null($last_error)) + $last_error = sprintf(esc_html__('Invalid post #%d.', 'wp-postratings'), $post_id); + return FALSE; + } + + // If Valid Post Then We Rate It + $ratings_max = intval(get_option('postratings_max')); + $ratings_custom = intval(get_option('postratings_customrating')); + $ratings_value = get_option('postratings_ratingsvalue'); + $post_ratings = get_post_custom($post_id); + $post_ratings_users = ! empty( $post_ratings['ratings_users'] ) ? intval($post_ratings['ratings_users'][0]) : 0; + $post_ratings_score = ! empty( $post_ratings['ratings_score'] ) ? intval($post_ratings['ratings_score'][0]) : 0; + // Check For Ratings Lesser Than 1 And Greater Than $ratings_max + if($rate < 1 || $rate > $ratings_max) { + $rate = 0; + } + $post_ratings_users = ($post_ratings_users+1); + $post_ratings_score = ($post_ratings_score+intval($ratings_value[$rate-1])); + $post_ratings_average = round($post_ratings_score/$post_ratings_users, 2); + update_post_meta($post_id, 'ratings_users', $post_ratings_users); + update_post_meta($post_id, 'ratings_score', $post_ratings_score); + update_post_meta($post_id, 'ratings_average', $post_ratings_average); + + // Add Log + if(!empty($user_identity)) { + $rate_user = $user_identity; + } elseif(!empty($_COOKIE['comment_author_'.COOKIEHASH])) { + $rate_user = $_COOKIE['comment_author_'.COOKIEHASH]; + } else { + $rate_user = __('Guest', 'wp-postratings'); + } + $rate_user = apply_filters( 'wp_postratings_process_ratings_user', $rate_user ); + $rate_userid = apply_filters( 'wp_postratings_process_ratings_userid', intval( $user_ID ) ); + + // Only Create Cookie If User Choose Logging Method 1 Or 3 + $postratings_logging_method = intval(get_option('postratings_logging_method')); + if($postratings_logging_method == 1 || $postratings_logging_method == 3) { + $rate_cookie = setcookie("rated_" . $post_id, + $ratings_value[$rate-1], + apply_filters('wp_postratings_cookie_expiration', (time() + 30000000) ), + apply_filters('wp_postratings_cookiepath', SITECOOKIEPATH)); + } + + // Log Ratings No Matter What + $rate_log = $wpdb->insert( $wpdb->prefix . "ratings", + array(// 'rating_id' => 0, autoinc + 'rating_postid' => $post_id, + 'rating_posttitle' => $post->post_title, + 'rating_rating' => $ratings_value[$rate-1], + 'rating_timestamp' => current_time('timestamp'), + 'rating_ip' => get_ipaddress(), + 'rating_host' => @gethostbyaddr( get_ipaddress() ), + 'rating_username' => $rate_user, + 'rating_userid' => $rate_userid), + array('%d', '%s', '%d', '%d', '%s', '%s', '%s', '%d') ); + + $last_id = $wpdb->insert_id; + // Allow Other Plugins To Hook When A Post Is Rated + do_action('rate_post', $rate_userid, $post_id, $ratings_value[$rate-1]); + // Output AJAX Result + return the_ratings_results($post_id, $post_ratings_users, $post_ratings_score, $post_ratings_average); - // Log Ratings No Matter What - $rate_log = $wpdb->insert( $wpdb->prefix . "ratings", - array(// 'rating_id' => 0, autoinc - 'rating_postid' => $post_id, - 'rating_posttitle' => $post->post_title, - 'rating_rating' => $ratings_value[$rate-1], - 'rating_timestamp' => current_time('timestamp'), - 'rating_ip' => get_ipaddress(), - 'rating_host' => @gethostbyaddr( get_ipaddress() ), - 'rating_username' => $rate_user, - 'rating_userid' => $rate_userid), - array('%d', '%s', '%d', '%d', '%s', '%s', '%s', '%d') ); - - $last_id = $wpdb->insert_id; - // Allow Other Plugins To Hook When A Post Is Rated - do_action('rate_post', $rate_userid, $post_id, $ratings_value[$rate-1]); - // Output AJAX Result - return the_ratings_results($post_id, $post_ratings_users, $post_ratings_score, $post_ratings_average); - } // End if($rate && $post_id && check_allowtorate()) } From eaa849328208f8ab6d2080f0c87cf968659a75d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Droz?= Date: Sat, 8 Jul 2017 02:01:19 -0300 Subject: [PATCH 08/32] comment+vote: use error messages that process_ratings() send by ref --- wp-postratings.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/wp-postratings.php b/wp-postratings.php index cb2f2ae..428d44b 100644 --- a/wp-postratings.php +++ b/wp-postratings.php @@ -1288,11 +1288,12 @@ function process_ratings_from_comment($comment_id) { return; } - $rate_id = 0; - process_ratings($post_id, $rate, $rate_id); + $rate_id = 0; $last_error = ''; + process_ratings($post_id, $rate, $rate_id, $last_error); if ($rate_id) { add_comment_meta( $comment_id, 'postratings_id', $rate_id ); } + // if $last_error: ToDo } add_filter( 'comments_array', 'show_rating_in_comment' ); From 5947bff002a5424501cdd830c81b9ecab36669ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Droz?= Date: Sat, 8 Jul 2017 02:02:46 -0300 Subject: [PATCH 09/32] comment+vote: REST API: added a handler for comment+vote from the WP >=4.7 REST API facility --- wp-postratings.php | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/wp-postratings.php b/wp-postratings.php index 428d44b..9a99695 100644 --- a/wp-postratings.php +++ b/wp-postratings.php @@ -1296,6 +1296,31 @@ function process_ratings_from_comment($comment_id) { // if $last_error: ToDo } +// to be called from the "update_callback" of register_rest_field() +function process_ratings_from_rest_API( WP_Comment $comment, $rate ) { + if (! $comment->comment_post_ID || ! $rate) { + // ToDo + return; + } + + $allow_to_vote_with_comment = intval(get_option('postratings_onlyifcomment')); + if (! $allow_to_vote_with_comment) { + return; + } + + $rate_id = 0; $last_error = ''; + process_ratings($comment->comment_post_ID, $rate, $rate_id, $last_error); + if ($rate_id) { + add_comment_meta( $comment_id, 'postratings_id', $rate_id ); + return true; + } + elseif ($last_error) { + var_dump($last_error); + return new WP_Error( 'rest_comment_vote_invalid', $last_error, array( 'status' => 403 ) ); + } + return false; +} + add_filter( 'comments_array', 'show_rating_in_comment' ); function show_rating_in_comment($comments) { if( ! count( $comments ) ) return; From 1c9b9321df0f3d9e080bad7b5abfbf46509e0ca8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Droz?= Date: Sat, 8 Jul 2017 02:04:38 -0300 Subject: [PATCH 10/32] comment+vote: moved code into its own PHP file --- includes/postratings-comment.php | 96 ++++++++++++++++++++++++++++++++ wp-postratings.php | 90 +----------------------------- 2 files changed, 97 insertions(+), 89 deletions(-) create mode 100644 includes/postratings-comment.php diff --git a/includes/postratings-comment.php b/includes/postratings-comment.php new file mode 100644 index 0000000..b4d1b39 --- /dev/null +++ b/includes/postratings-comment.php @@ -0,0 +1,96 @@ +comment_ID, 'postratings_id', true); + if (intval($rate_id)) { + $rate = $wpdb->get_var( $wpdb->prepare( "SELECT rating_rating FROM {$wpdb->ratings} WHERE rating_id = %d", intval($rate_id)) ); + if ($rate) { + $comment->comment_content .= '

' + . esc_html(sprintf(__('Rated %d', 'wp-postratings'), $rate)) + . '

'; + } + } + } + + return $comments; +} +add_filter( 'manage_edit-comments_columns', 'comment_has_vote' ); +function comment_has_vote( $columns ) { + $columns['comment-vote'] = __( 'Vote', 'wp-postratings' ); + return $columns; +} + + +add_filter( 'manage_comments_custom_column', 'recent_comment_has_vote', 20, 2 ); +function recent_comment_has_vote( $column_name, $comment_id ) { + if( 'comment-vote' != strtolower( $column_name ) ) return; + if ( ( $rate_id = get_comment_meta( $comment_id, 'postratings_id', true ) ) ) { + if (intval($rate_id)) { + global $wpdb; + $rate = $wpdb->get_var( $wpdb->prepare( "SELECT rating_rating FROM {$wpdb->ratings} WHERE rating_id = %d", intval($rate_id)) ); + if ($rate) { + printf(__('Rated at %d', 'wp-postratings'), $rate); + } + } + } + + return $options; +} + + +// REST API specific +// to be called from the "update_callback" of register_rest_field() +function process_ratings_from_rest_API( WP_Comment $comment, $rate ) { + if (! $comment->comment_post_ID || ! $rate) { + // ToDo + return; + } + + $allow_to_vote_with_comment = intval(get_option('postratings_onlyifcomment')); + if (! $allow_to_vote_with_comment) { + return; + } + + $rate_id = 0; $last_error = ''; + process_ratings($comment->comment_post_ID, $rate, $rate_id, $last_error); + if ($rate_id) { + add_comment_meta( $comment_id, 'postratings_id', $rate_id ); + return true; + } + elseif ($last_error) { + var_dump($last_error); + return new WP_Error( 'rest_comment_vote_invalid', $last_error, array( 'status' => 403 ) ); + } + return false; +} diff --git a/wp-postratings.php b/wp-postratings.php index 9a99695..6c90ec7 100644 --- a/wp-postratings.php +++ b/wp-postratings.php @@ -60,6 +60,7 @@ require_once( 'includes/postratings-shortcodes.php' ); require_once( 'includes/postratings-stats.php' ); require_once( 'includes/postratings-widgets.php' ); +require_once( 'includes/postratings-comment.php' ); /** * Register plugin activation hook @@ -1273,92 +1274,3 @@ function expand_ratings_template($template, $post_data, $post_ratings_data = nul return apply_filters( 'expand_ratings_template', ( $value . $google_structured_data ) ); } - -add_filter( 'wp_insert_comment', 'process_ratings_from_comment' ); -function process_ratings_from_comment($comment_id) { - $post_id = intval($_POST['comment_post_ID']); - $rate = intval($_POST["wp_postrating_form_value_$post_id"]); - if (! $post_id || ! $rate) { - // ignored (could be simply a second comment while missing a second vote) - return; - } - - $allow_to_vote_with_comment = intval(get_option('postratings_onlyifcomment')); - if (! $allow_to_vote_with_comment) { - return; - } - - $rate_id = 0; $last_error = ''; - process_ratings($post_id, $rate, $rate_id, $last_error); - if ($rate_id) { - add_comment_meta( $comment_id, 'postratings_id', $rate_id ); - } - // if $last_error: ToDo -} - -// to be called from the "update_callback" of register_rest_field() -function process_ratings_from_rest_API( WP_Comment $comment, $rate ) { - if (! $comment->comment_post_ID || ! $rate) { - // ToDo - return; - } - - $allow_to_vote_with_comment = intval(get_option('postratings_onlyifcomment')); - if (! $allow_to_vote_with_comment) { - return; - } - - $rate_id = 0; $last_error = ''; - process_ratings($comment->comment_post_ID, $rate, $rate_id, $last_error); - if ($rate_id) { - add_comment_meta( $comment_id, 'postratings_id', $rate_id ); - return true; - } - elseif ($last_error) { - var_dump($last_error); - return new WP_Error( 'rest_comment_vote_invalid', $last_error, array( 'status' => 403 ) ); - } - return false; -} - -add_filter( 'comments_array', 'show_rating_in_comment' ); -function show_rating_in_comment($comments) { - if( ! count( $comments ) ) return; - global $wpdb; - - foreach( $comments as $comment ) { - $rate_id = get_comment_meta($comment->comment_ID, 'postratings_id', true); - if (intval($rate_id)) { - $rate = $wpdb->get_var( $wpdb->prepare( "SELECT rating_rating FROM {$wpdb->ratings} WHERE rating_id = %d", intval($rate_id)) ); - if ($rate) { - $comment->comment_content .= '

' - . esc_html(sprintf(__('Rated %d', 'wp-postratings'), $rate)) - . '

'; - } - } - } - - return $comments; -} -add_filter( 'manage_edit-comments_columns', 'comment_has_vote' ); -function comment_has_vote( $columns ) { - $columns['comment-vote'] = __( 'Vote', 'wp-postratings' ); - return $columns; -} - - -add_filter( 'manage_comments_custom_column', 'recent_comment_has_vote', 20, 2 ); -function recent_comment_has_vote( $column_name, $comment_id ) { - if( 'comment-vote' != strtolower( $column_name ) ) return; - if ( ( $rate_id = get_comment_meta( $comment_id, 'postratings_id', true ) ) ) { - if (intval($rate_id)) { - global $wpdb; - $rate = $wpdb->get_var( $wpdb->prepare( "SELECT rating_rating FROM {$wpdb->ratings} WHERE rating_id = %d", intval($rate_id)) ); - if ($rate) { - printf(__('Rated at %d', 'wp-postratings'), $rate); - } - } - } - - return $options; -} From 68e502f3c3ea09954d00ed145cc1e1284386596c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Droz?= Date: Thu, 29 Jun 2017 03:38:28 -0300 Subject: [PATCH 11/32] captcha: added recaptcha support inherited from contact-form-7 --- includes/postratings-captcha.php | 43 ++++++++++++++++++++++++++++++++ includes/postratings-scripts.php | 1 + js/postratings-js.dev.js | 23 ++++++++++++++++- js/postratings-js.js | 10 +------- postratings-options.php | 31 +++++++++++++++++++++-- wp-postratings.php | 10 ++++++++ 6 files changed, 106 insertions(+), 12 deletions(-) create mode 100644 includes/postratings-captcha.php diff --git a/includes/postratings-captcha.php b/includes/postratings-captcha.php new file mode 100644 index 0000000..8bd603d --- /dev/null +++ b/includes/postratings-captcha.php @@ -0,0 +1,43 @@ +is_active() ) { + return false; + } + + return $recaptcha->get_sitekey(); +} + +function recaptcha_is_enabled() { + if (! ($opt = get_option('postratings_options')) ) { + return false; + } + if (! isset($opt['recaptcha']) || ! $opt['recaptcha']) { + return false; + } + + return true; +} + +function is_human() { + $recaptcha = WPCF7_RECAPTCHA::get_instance(); + $response_token = wpcf7_recaptcha_response(); + // return true for mutants and humans + return $recaptcha->verify( $response_token ); +} + + +add_action( 'wp_enqueue_scripts', 'google_recaptcha' ); +function google_recaptcha() { + if ( ! recaptcha_is_enabled() ) return; + if ( ! recaptcha_is_op() ) return; + wp_register_script( 'google-recaptcha', + add_query_arg( [ 'onload' => 'recaptchaCallback', 'render' => 'explicit' ], + 'https://www.google.com/recaptcha/api.js' ), + [], '2.0', true ); +} diff --git a/includes/postratings-scripts.php b/includes/postratings-scripts.php index 1310760..c735304 100644 --- a/includes/postratings-scripts.php +++ b/includes/postratings-scripts.php @@ -74,5 +74,6 @@ function ratings_script_config($ajax = TRUE) { 'show_loading' => intval($postratings_ajax_style['loading']), 'show_fading' => intval($postratings_ajax_style['fading']), 'custom' => boolval( get_option( 'postratings_customrating', false ) ), + 'captcha_sitekey' => recaptcha_is_enabled() ? recaptcha_is_op() : false, )); } diff --git a/js/postratings-js.dev.js b/js/postratings-js.dev.js index 16cf652..cbb3534 100644 --- a/js/postratings-js.dev.js +++ b/js/postratings-js.dev.js @@ -19,6 +19,7 @@ // Variables var $j = jQuery.noConflict(); var is_being_rated = false; +var postratings_captcha = null; ratingsL10n.custom = parseInt(ratingsL10n.custom); ratingsL10n.max = parseInt(ratingsL10n.max); ratingsL10n.show_loading = parseInt(ratingsL10n.show_loading); @@ -114,6 +115,8 @@ function rate_post_success(post_id, data) { // Process Post Ratings function rate_post(post_id, post_rating) { var post_ratings_el = $j('#post-ratings-' + post_id); + var captcha_response; + if (! ratingsL10n.ajax_url) { var value_holder = $j('input[name="wp_postrating_form_value_' + post_id + '"]'); var curval = $j(value_holder).val(); @@ -126,6 +129,23 @@ function rate_post(post_id, post_rating) { return; } + if(ratingsL10n.captcha_sitekey && ratingsL10n.captcha_sitekey.length) { + if (postratings_captcha === null) { + postratings_captcha = grecaptcha.render("g-recaptcha-response", {"sitekey":ratingsL10n.captcha_sitekey}); + return; + } else { + captcha_response = grecaptcha.getResponse(postratings_captcha); + if (! grecaptcha.getResponse(postratings_captcha)) { + // grecaptcha.reset(postratings_captcha); + return; + } + else { + // ok, let's submit + $j('#g-recaptcha-response').remove(); + } + } + } + if(!is_being_rated) { var post_ratings_nonce = $j(post_ratings_el).data('nonce'); if(typeof post_ratings_nonce == 'undefined' || post_ratings_nonce == null) @@ -142,10 +162,11 @@ function rate_post(post_id, post_rating) { $j('#post-ratings-' + post_id + '-loading').show(); } } + $j.post({xhrFields: {withCredentials: true}, dataType: 'html', url: ratingsL10n.ajax_url, - data: 'action=postratings&pid=' + post_id + '&rate=' + post_rating + '&postratings_' + post_id + '_nonce=' + post_ratings_nonce, + data: 'action=postratings&pid=' + post_id + '&rate=' + post_rating + '&postratings_' + post_id + '_nonce=' + post_ratings_nonce + '&g-recaptcha-response=' + captcha_response, cache: false}) .done(function(data) { rate_post_success(post_id, data); }); } diff --git a/js/postratings-js.js b/js/postratings-js.js index ceb23ef..781c1b5 100644 --- a/js/postratings-js.js +++ b/js/postratings-js.js @@ -1,9 +1 @@ -var post_id=0,post_rating=0,is_being_rated=!1;ratingsL10n.custom=parseInt(ratingsL10n.custom);ratingsL10n.max=parseInt(ratingsL10n.max);ratingsL10n.show_loading=parseInt(ratingsL10n.show_loading);ratingsL10n.show_fading=parseInt(ratingsL10n.show_fading); -function current_rating(a,b,c){if(!is_being_rated){post_id=a;post_rating=b;if(ratingsL10n.custom&&2==ratingsL10n.max)jQuery("#rating_"+post_id+"_"+b).attr("src",eval("ratings_"+b+"_mouseover_image.src"));else for(i=1;i<=b;i++)ratingsL10n.custom?jQuery("#rating_"+post_id+"_"+i).attr("src",eval("ratings_"+i+"_mouseover_image.src")):jQuery("#rating_"+post_id+"_"+i).attr("src",ratings_mouseover_image.src);jQuery("#ratings_"+post_id+"_text").length&&(jQuery("#ratings_"+post_id+"_text").show(),jQuery("#ratings_"+ - post_id+"_text").html(c))}} -function ratings_off(a,b,c){if(!is_being_rated){for(i=1;i<=ratingsL10n.max;i++)i<=a?ratingsL10n.custom?jQuery("#rating_"+post_id+"_"+i).attr("src",ratingsL10n.plugin_url+"/images/"+ratingsL10n.image+"/rating_"+i+"_on."+ratingsL10n.image_ext):jQuery("#rating_"+post_id+"_"+i).attr("src",ratingsL10n.plugin_url+"/images/"+ratingsL10n.image+"/rating_on."+ratingsL10n.image_ext):i==b?ratingsL10n.custom?jQuery("#rating_"+post_id+"_"+i).attr("src",ratingsL10n.plugin_url+"/images/"+ratingsL10n.image+"/rating_"+ - i+"_half"+(c?"-rtl":"")+"."+ratingsL10n.image_ext):jQuery("#rating_"+post_id+"_"+i).attr("src",ratingsL10n.plugin_url+"/images/"+ratingsL10n.image+"/rating_half"+(c?"-rtl":"")+"."+ratingsL10n.image_ext):ratingsL10n.custom?jQuery("#rating_"+post_id+"_"+i).attr("src",ratingsL10n.plugin_url+"/images/"+ratingsL10n.image+"/rating_"+i+"_off."+ratingsL10n.image_ext):jQuery("#rating_"+post_id+"_"+i).attr("src",ratingsL10n.plugin_url+"/images/"+ratingsL10n.image+"/rating_off."+ratingsL10n.image_ext);jQuery("#ratings_"+ - post_id+"_text").length&&(jQuery("#ratings_"+post_id+"_text").hide(),jQuery("#ratings_"+post_id+"_text").empty())}}function set_is_being_rated(a){is_being_rated=a}function rate_post_success(a){jQuery("#post-ratings-"+post_id).html(a);ratingsL10n.show_loading&&jQuery("#post-ratings-"+post_id+"-loading").hide();ratingsL10n.show_fading?jQuery("#post-ratings-"+post_id).fadeTo("def",1,function(){set_is_being_rated(!1)}):set_is_being_rated(!1)} -function rate_post(){post_ratings_el=jQuery("#post-ratings-"+post_id);if(is_being_rated)alert(ratingsL10n.text_wait);else{post_ratings_nonce=jQuery(post_ratings_el).data("nonce");if("undefined"==typeof post_ratings_nonce||null==post_ratings_nonce)post_ratings_nonce=jQuery(post_ratings_el).attr("data-nonce");set_is_being_rated(!0);ratingsL10n.show_fading?jQuery(post_ratings_el).fadeTo("def",0,function(){ratingsL10n.show_loading&&jQuery("#post-ratings-"+post_id+"-loading").show();jQuery.ajax({type:"POST", - xhrFields:{withCredentials:!0},dataType:"html",url:ratingsL10n.ajax_url,data:"action=postratings&pid="+post_id+"&rate="+post_rating+"&postratings_"+post_id+"_nonce="+post_ratings_nonce,cache:!1,success:rate_post_success})}):(ratingsL10n.show_loading&&jQuery("#post-ratings-"+post_id+"-loading").show(),jQuery.ajax({type:"POST",xhrFields:{withCredentials:!0},dataType:"html",url:ratingsL10n.ajax_url,data:"action=postratings&pid="+post_id+"&rate="+post_rating+"&postratings_"+post_id+"_nonce="+post_ratings_nonce, - cache:!1,success:rate_post_success}))}}; \ No newline at end of file +function current_rating(t,a){if(!ratingsL10n.ajax_url){var n=$j('input[name="wp_postrating_form_value_'+t+'"]');if(parseInt($j(n).val()))return}if(!is_being_rated){if(ratingsL10n.custom&&2==ratingsL10n.max)document.getElementById("rating_"+t+"_"+a).src=ratings_mouseover_image[r].src;else for(var r=1;r<=a;r++)document.getElementById("rating_"+t+"_"+r).src=ratingsL10n.custom?ratings_mouseover_image[r].src:ratings_mouseover_image.src;jQuery("#ratings_"+t+"_text").length&&jQuery("#ratings_"+t+"_text").html(jQuery("#rating_"+t+"_"+a).data("ratingsText")).show()}}function ratings_off(t,a,n,r){var e;if((ratingsL10n.ajax_url||(e=$j('input[name="wp_postrating_form_value_'+t+'"]'),!parseInt($j(e).val())))&&!is_being_rated){for(var i=ratingsL10n.plugin_url+"/images/"+ratingsL10n.image+"/rating",s=1;s<=ratingsL10n.max;s++)e=document.getElementById("rating_"+t+"_"+s),s<=a?e.src=i+(ratingsL10n.custom?"_"+s:"")+"_on."+ratingsL10n.image_ext:s==n?e.src=i+(ratingsL10n.custom?"_"+s:"")+"_half"+(r?"-rtl":"")+"."+ratingsL10n.image_ext:e.src=i+(ratingsL10n.custom?"_"+s:"")+"_off."+ratingsL10n.image_ext;jQuery("#ratings_"+t+"_text").length&&jQuery("#ratings_"+t+"_text").hide().empty()}}function set_is_being_rated(t){is_being_rated=t}function rate_post_success(t,a){$j("#post-ratings-"+t).html(a),ratingsL10n.show_loading&&$j("#post-ratings-"+t+"-loading").hide(),ratingsL10n.show_fading?$j("#post-ratings-"+t).fadeTo("def",1,function(){set_is_being_rated(!1)}):set_is_being_rated(!1)}function rate_post(t,a){var n,r=$j("#post-ratings-"+t);if(!ratingsL10n.ajax_url){var e=$j('input[name="wp_postrating_form_value_'+t+'"]'),i=$j(e).val();return $j(e).val(null),$j("#rating_"+t+"_"+i).trigger("mouseout"),void(i!=a&&($j("#rating_"+t+"_"+a).trigger("mouseover"),$j(e).val(a)))}if(ratingsL10n.captcha_sitekey&&ratingsL10n.captcha_sitekey.length){if(null===postratings_captcha)return void(postratings_captcha=grecaptcha.render("g-recaptcha-response",{sitekey:ratingsL10n.captcha_sitekey}));if(n=grecaptcha.getResponse(postratings_captcha),!grecaptcha.getResponse(postratings_captcha))return;$j("#g-recaptcha-response").remove()}if(is_being_rated)alert(ratingsL10n.text_wait);else{var s=$j(r).data("nonce");"undefined"!=typeof s&&null!=s||(s=$j(r).attr("data-nonce")),set_is_being_rated(!0),ratingsL10n.show_fading?$j(r).fadeTo("def",0,function(){ratingsL10n.show_loading&&$j("#post-ratings-"+t+"-loading").show()}):ratingsL10n.show_loading&&$j("#post-ratings-"+t+"-loading").show(),$j.post({xhrFields:{withCredentials:!0},dataType:"html",url:ratingsL10n.ajax_url,data:"action=postratings&pid="+t+"&rate="+a+"&postratings_"+t+"_nonce="+s+"&g-recaptcha-response="+n,cache:!1}).done(function(a){rate_post_success(t,a)})}}var $j=jQuery.noConflict(),is_being_rated=!1,postratings_captcha=null;ratingsL10n.custom=parseInt(ratingsL10n.custom),ratingsL10n.max=parseInt(ratingsL10n.max),ratingsL10n.show_loading=parseInt(ratingsL10n.show_loading),ratingsL10n.show_fading=parseInt(ratingsL10n.show_fading);var ratings_mouseover_image;if(ratingsL10n.custom){ratings_mouseover_image=[];for(var i=1;i<=ratingsL10n.max;i++)ratings_mouseover_image[i]=new Image,ratings_mouseover_image[i].src=ratingsL10n.plugin_url+"/images/"+ratingsL10n.image+"/rating_"+i+"_over."+ratingsL10n.image_ext}else ratings_mouseover_image=new Image,ratings_mouseover_image.src=ratingsL10n.plugin_url+"/images/"+ratingsL10n.image+"/rating_over."+ratingsL10n.image_ext; \ No newline at end of file diff --git a/postratings-options.php b/postratings-options.php index a71b1b0..ed1e3db 100644 --- a/postratings-options.php +++ b/postratings-options.php @@ -43,6 +43,7 @@ $postratings_image = sanitize_text_field( trim( $_POST['postratings_image'] ) ); $postratings_max = intval($_POST['postratings_max']); $postratings_richsnippet = intval($_POST['postratings_richsnippet']); + $postratings_recaptcha = is_plugin_active('contact-form-7/wp-contact-form-7.php') && recaptcha_is_op() ? boolval($_POST['postratings_recaptcha']) : false; $postratings_ratingstext_array = $_POST['postratings_ratingstext']; $postratings_ratingstext = array(); if( ! empty( $postratings_ratingstext_array ) && is_array( $postratings_ratingstext_array ) ) { @@ -64,7 +65,7 @@ $postratings_allowtorate = intval($_POST['postratings_allowtorate']); $update_ratings_queries = array(); $update_ratings_text = array(); - $postratings_options = array('richsnippet' => $postratings_richsnippet); + $postratings_options = array('richsnippet' => $postratings_richsnippet, 'recaptcha' => $postratings_recaptcha); $update_ratings_queries[] = update_option('postratings_customrating', $postratings_customrating); $update_ratings_queries[] = update_option('postratings_template_vote', $postratings_template_vote); $update_ratings_queries[] = update_option('postratings_template_text', $postratings_template_text); @@ -306,6 +307,32 @@ function set_custom(custom, max) { />  + +
+ + + + @@ -438,4 +465,4 @@ function set_custom(custom, max) {

- \ No newline at end of file + diff --git a/wp-postratings.php b/wp-postratings.php index 6c90ec7..7f6e6f5 100644 --- a/wp-postratings.php +++ b/wp-postratings.php @@ -56,6 +56,7 @@ require_once( 'includes/postratings-activation.php' ); require_once( 'includes/postratings-admin.php' ); require_once( 'includes/postratings-i18n.php' ); +require_once( 'includes/postratings-captcha.php' ); require_once( 'includes/postratings-scripts.php' ); require_once( 'includes/postratings-shortcodes.php' ); require_once( 'includes/postratings-stats.php' ); @@ -135,6 +136,9 @@ function get_the_ratings($start_tag = 'div', $custom_id = 0, $ajax) { if (! $ajax) { $html_string .= '' . "\n"; } + if ( recaptcha_is_enabled() && recaptcha_is_op() ) { + $html_string .= '
'; + } return $html_string . "<$start_tag $attributes data-nonce=\"".wp_create_nonce('postratings_'.$ratings_id.'-nonce')."\">".the_ratings_vote($ratings_id).''.$loading; } } @@ -578,6 +582,12 @@ function process_ratings($post_id, $rate, &$last_id = NULL, &$last_error = NULL) return FALSE; } + if (recaptcha_is_enabled() && recaptcha_is_op() && ! is_human()) { + if (! is_null($last_error)) + $last_error = sprintf(esc_html__('invalid captcha.', 'wp-postratings')); + return FALSE; + } + // If Valid Post Then We Rate It $ratings_max = intval(get_option('postratings_max')); $ratings_custom = intval(get_option('postratings_customrating')); From f9037a53febe3f5717b7b4949a363d9b3e52e519 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Droz?= Date: Thu, 29 Jun 2017 00:23:51 -0300 Subject: [PATCH 12/32] scoring: added a bayesian average calculation helper. Avoid little-evaluated high-noted items to overcome vastly-evaluated items. Ex with (0,2,3,11,5) vs (0,0,3,1,3): Traditional scoring: 2.9 vs 3.2. Bayesian scoring with 90% confidence: 3.4 vs 3.0 --- includes/postratings-bayesian-score.php | 81 +++++++++++++++++++++++++ includes/postratings-tests.php | 44 ++++++++++++++ wp-postratings.php | 1 + 3 files changed, 126 insertions(+) create mode 100644 includes/postratings-bayesian-score.php create mode 100644 includes/postratings-tests.php diff --git a/includes/postratings-bayesian-score.php b/includes/postratings-bayesian-score.php new file mode 100644 index 0000000..4446b62 --- /dev/null +++ b/includes/postratings-bayesian-score.php @@ -0,0 +1,81 @@ + $nk) { + $asum[] = $sk * ($nk+1); + } + return array_sum($asum) / ($N+$K); + } + } + + $fsns = f($s, $ns); + return $fsns - $z * sqrt( ( f($s2, $ns) - pow($fsns, 2)) / ($N+$K+1) ); +} + +function get_post_score_data($post_id) { + global $wpdb; + + $def = []; + $f = $wpdb->get_results( $wpdb->prepare( "SELECT rating_rating as r, count(1) as c FROM {$wpdb->ratings} WHERE rating_postid = %d GROUP BY rating_rating", $post_id )); + foreach($f as $data) $def[$data->r] = (int)$data->c; + $def += array_fill( 1, intval( get_option( 'postratings_max', 5 ) ), 0 ); + ksort( $def ); + + return $def; +} + +function get_bayesian_score($post_id, $confidence) { + return bayesian_score( get_post_score_data( $post_id ), $confidence ); +} + + +/* ToDo: how to produce a dynamically generated field (with no stored data at all?) + If it's not possible, we may consider (optionnally) storing the alternative average + inside the DB too */ +/* +function get_postrating_bayesian_score($metadata, $object_id, $meta_key, $single) { + if ($meta_key && $meta_key == 'bayesian_score') { + return get_bayesian_score($object_id, floatval(constant('NUM_VOTES_IMPACT_' . intval(get_option('bayesian_votes_impact', 90)))) ? : NUM_VOTES_IMPACT_90); + } +} +add_filter('get_post_metadata', 'get_postrating_bayesian_score', 10, 4); +*/ diff --git a/includes/postratings-tests.php b/includes/postratings-tests.php new file mode 100644 index 0000000..c49d72c --- /dev/null +++ b/includes/postratings-tests.php @@ -0,0 +1,44 @@ + 0 ? "\t " : ($d < 0 ? "\t" : '')), + $d != 0 ? sprintf("%.2f", $d) : ""); + } +} + +function get_post_rating_detail($stats) { + global $wpdb; + + $post_stats = []; + foreach($wpdb->get_results("SELECT distinct rating_postid as p FROM {$wpdb->ratings}") as $i) { + $post_stats[] = get_post_score_data($i->p); + } + + postratings_score_tests(NUM_VOTES_IMPACT_90, $post_stats); +} diff --git a/wp-postratings.php b/wp-postratings.php index 7f6e6f5..53784c9 100644 --- a/wp-postratings.php +++ b/wp-postratings.php @@ -62,6 +62,7 @@ require_once( 'includes/postratings-stats.php' ); require_once( 'includes/postratings-widgets.php' ); require_once( 'includes/postratings-comment.php' ); +require_once( 'includes/postratings-bayesian-score.php' ); /** * Register plugin activation hook From 719512445b535157e6b2b119afc628650ff47ed0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Droz?= Date: Sun, 30 Jul 2017 00:54:06 -0300 Subject: [PATCH 13/32] bugfix: removed a spurious return $options --- includes/postratings-comment.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/includes/postratings-comment.php b/includes/postratings-comment.php index b4d1b39..11c8396 100644 --- a/includes/postratings-comment.php +++ b/includes/postratings-comment.php @@ -64,8 +64,6 @@ function recent_comment_has_vote( $column_name, $comment_id ) { } } } - - return $options; } From d92ba697eaf3fc9ba2cd083fa5d47c17734dc70c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Droz?= Date: Sun, 30 Jul 2017 03:26:37 -0300 Subject: [PATCH 14/32] return NULL for empty scores --- includes/postratings-bayesian-score.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/includes/postratings-bayesian-score.php b/includes/postratings-bayesian-score.php index 4446b62..bfbcd42 100644 --- a/includes/postratings-bayesian-score.php +++ b/includes/postratings-bayesian-score.php @@ -29,6 +29,8 @@ function weighted_score($ns) { // https://stackoverflow.com/a/40958702 // http://www.evanmiller.org/ranking-items-with-star-ratings.html function bayesian_score($ns, $confidence) { + if (empty(array_filter($ns))) return NULL; + $ns = array_reverse($ns); $N = array_sum($ns); $K = count($ns); From a4ecde56b3dd66107cf1cfe271faa2c2ab46b3d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Droz?= Date: Wed, 9 Aug 2017 00:02:14 -0300 Subject: [PATCH 15/32] bugfix: regression from 5225aaec: was showing half-stars instead of the correct image pattern --- wp-postratings.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wp-postratings.php b/wp-postratings.php index 53784c9..84fac84 100644 --- a/wp-postratings.php +++ b/wp-postratings.php @@ -1031,12 +1031,12 @@ function get_ratings_images_vote($post_id, $ratings_custom, $ratings_max, $post_ if($ratings_custom) { $rating_attr += array( - 'src' => get_rating_image_url($ratings_image, $i <= $post_rating ? 'on' : $i == $insert_half ? $use_custom_half_rtl ? 'half-rtl' : 'half' : 'off', $i), + 'src' => get_rating_image_url($ratings_image, $i <= $post_rating ? 'on' : ( $i == $insert_half ? ($use_custom_half_rtl ? 'half-rtl' : 'half') : 'off'), $i); 'onmouseout' => sprintf("ratings_off(%d, %d, %d, %d);", $post_id, $post_rating, $insert_half, $use_custom_half_rtl), ); } else { $rating_attr += array( - 'src' => get_rating_image_url($ratings_image, $i <= $post_rating ? 'on' : $i == $insert_half ? $use_half_rtl ? 'half-rtl' : 'half' : 'off', NULL), + 'src' => get_rating_image_url($ratings_image, $i <= $post_rating ? 'on' : ( $i == $insert_half ? ($use_half_rtl ? 'half-rtl' : 'half') : 'off') , NULL); 'onmouseout' => sprintf("ratings_off(%d, %d, %d, %d);", $post_id, $post_rating, $insert_half, $use_half_rtl), ); } From 4610207aa8ae80143b72dd795774542f0744416f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Droz?= Date: Wed, 9 Aug 2017 00:02:56 -0300 Subject: [PATCH 16/32] bugfix: regression from 5225aaec: spurious quote introduced when switching to here-document --- wp-postratings.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wp-postratings.php b/wp-postratings.php index 84fac84..aca8e30 100644 --- a/wp-postratings.php +++ b/wp-postratings.php @@ -1271,7 +1271,7 @@ function expand_ratings_template($template, $post_data, $post_ratings_data = nul $ratings_meta = ''; if( $post_ratings_average > 0 ) { $ratings_meta = << +
From f7fc7775676ecc1aacce2115a82bddf6f2b3dd48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Droz?= Date: Tue, 8 Aug 2017 21:51:49 -0300 Subject: [PATCH 17/32] 5225aaec followup: moved more javascript stuff outside of templates using data-* attribute and do the event binding later client-side (rewrite and vastly improve javascript logic) --- includes/postratings-scripts.php | 34 +++-- js/postratings-js.dev.js | 218 ++++++++++++++++++------------- wp-postratings.php | 44 ++++--- 3 files changed, 175 insertions(+), 121 deletions(-) diff --git a/includes/postratings-scripts.php b/includes/postratings-scripts.php index c735304..73b18bf 100644 --- a/includes/postratings-scripts.php +++ b/includes/postratings-scripts.php @@ -44,6 +44,22 @@ function ratings_scripts() { } wp_enqueue_script('wp-postratings', plugins_url('wp-postratings/js/postratings-js.dev.js'), array('jquery'), WP_POSTRATINGS_VERSION, true); + + // these are static JS parameters + $postratings_ajax_style = get_option( 'postratings_ajax_style' ); + wp_localize_script('wp-postratings', 'ratingsL10n', array( + 'plugin_url' => plugins_url( 'wp-postratings' ), + 'ajax_url' => admin_url('admin-ajax.php'), + 'text_wait' => __('Please rate only 1 item at a time.', 'wp-postratings'), + 'image' => get_option( 'postratings_image' ), + 'image_ext' => RATINGS_IMG_EXT, + 'max' => intval( get_option( 'postratings_max' ) ), + 'show_loading' => intval($postratings_ajax_style['loading']), + 'show_fading' => intval($postratings_ajax_style['fading']), + 'custom' => boolval( get_option( 'postratings_customrating', false ) ), + 'captcha_sitekey' => recaptcha_is_enabled() ? recaptcha_is_op() : false, + 'rtl' => intval( is_rtl() ) + )); } @@ -59,21 +75,3 @@ function ratings_scripts_admin($hook_suffix) { )); } } - -// this need to be triggered manually -function ratings_script_config($ajax = TRUE) { - $postratings_ajax_style = get_option( 'postratings_ajax_style' ); - - wp_localize_script('wp-postratings', 'ratingsL10n', array( - 'plugin_url' => plugins_url( 'wp-postratings' ), - 'ajax_url' => $ajax ? admin_url('admin-ajax.php') : FALSE, - 'text_wait' => __('Please rate only 1 item at a time.', 'wp-postratings'), - 'image' => get_option( 'postratings_image' ), - 'image_ext' => RATINGS_IMG_EXT, - 'max' => intval( get_option( 'postratings_max' ) ), - 'show_loading' => intval($postratings_ajax_style['loading']), - 'show_fading' => intval($postratings_ajax_style['fading']), - 'custom' => boolval( get_option( 'postratings_customrating', false ) ), - 'captcha_sitekey' => recaptcha_is_enabled() ? recaptcha_is_op() : false, - )); -} diff --git a/js/postratings-js.dev.js b/js/postratings-js.dev.js index cbb3534..b097c2d 100644 --- a/js/postratings-js.dev.js +++ b/js/postratings-js.dev.js @@ -1,102 +1,144 @@ /* -+----------------------------------------------------------------+ -| | -| WordPress Plugin: WP-PostRatings | -| Copyright (c) 2012 Lester "GaMerZ" Chan | -| | -| File Written By: | -| - Lester "GaMerZ" Chan | -| - http://lesterchan.net | -| | -| File Information: | -| - Post Ratings Javascript File | -| - wp-content/plugins/wp-postratings/postratings-js.php | -| | -+----------------------------------------------------------------+ -*/ + +----------------------------------------------------------------+ + | | + | WordPress Plugin: WP-PostRatings | + | Copyright (c) 2012 Lester "GaMerZ" Chan | + | Copyright (c) 2017 Raphaël Droz | + | | + | File Information: | + | - Post Ratings Javascript File | + | - wp-content/plugins/wp-postratings/postratings-js.php | + | | + +----------------------------------------------------------------+ + */ // Variables var $j = jQuery.noConflict(); var is_being_rated = false; var postratings_captcha = null; -ratingsL10n.custom = parseInt(ratingsL10n.custom); -ratingsL10n.max = parseInt(ratingsL10n.max); -ratingsL10n.show_loading = parseInt(ratingsL10n.show_loading); -ratingsL10n.show_fading = parseInt(ratingsL10n.show_fading); - - var ratings_mouseover_image; -if(ratingsL10n.custom) { - ratings_mouseover_image = []; - for(var i = 1; i <= ratingsL10n.max; i++) { - ratings_mouseover_image[i] = new Image(); - ratings_mouseover_image[i].src = ratingsL10n.plugin_url + "/images/" + ratingsL10n.image + "/rating_" + i + "_over." + ratingsL10n.image_ext ; - } -} else { - ratings_mouseover_image = new Image(); - ratings_mouseover_image.src = ratingsL10n.plugin_url + "/images/" + ratingsL10n.image + "/rating_over." + ratingsL10n.image_ext ; -} -// When User Mouse Over Ratings -function current_rating(post_id, post_rating) { - if (! ratingsL10n.ajax_url) { - var element = $j('input[name="wp_postrating_form_value_' + post_id + '"]'); - // mouseout, but a value was click/selected in order to be later POSTed: do nothing - if (parseInt($j(element).val())) { - return; +jQuery(function($) { + ratingsL10n.custom = parseInt(ratingsL10n.custom); + ratingsL10n.max = parseInt(ratingsL10n.max); + ratingsL10n.show_loading = parseInt(ratingsL10n.show_loading); + ratingsL10n.show_fading = parseInt(ratingsL10n.show_fading); + ratingsL10n.baseimg = ratingsL10n.plugin_url + '/images/' + ratingsL10n.image + '/rating' ; + ratingsL10n.rtl = parseInt(ratingsL10n.rtl); + + if(ratingsL10n.custom) { + ratings_mouseover_image = []; + for(var i = 1; i <= ratingsL10n.max; i++) { + ratings_mouseover_image[i] = new Image(); + ratings_mouseover_image[i].src = ratingsL10n.baseimg + "_" + i + "_over." + ratingsL10n.image_ext ; } + } else { + ratings_mouseover_image = new Image(); + ratings_mouseover_image.src = ratingsL10n.baseimg + "_over." + ratingsL10n.image_ext ; } - if(!is_being_rated) { - if(ratingsL10n.custom && ratingsL10n.max == 2) { - document.getElementById('rating_' + post_id + '_' + post_rating).src = ratings_mouseover_image[i].src; - } else { - for(var i = 1; i <= post_rating; i++) { - document.getElementById('rating_' + post_id + '_' + i).src = ratingsL10n.custom ? ratings_mouseover_image[i].src : ratings_mouseover_image.src; - } - } - if(jQuery('#ratings_' + post_id + '_text').length) { - jQuery('#ratings_' + post_id + '_text').html(jQuery('#rating_' + post_id + '_' + post_rating).data('ratingsText')).show(); - } + $('img[data-votes]') + .on('mouseover mouseout', current_rating) + .on('click keypress', rate_post); + +}); + +// intermediary functions: wrap RTL complexity (invert on/off) +function getRtlI(i) { return (!ratingsL10n.rtl) ? i : (ratingsL10n.max - i + 1); } +function getOver(i) { return ratingsL10n.custom ? ratings_mouseover_image[ getRtlI(i) ].src : ratings_mouseover_image.src; } +function getOn(i) { return ratingsL10n.baseimg + (ratingsL10n.custom ? '_' + getRtlI(i) : '') + '_' + getRtlDir('on') + '.' + ratingsL10n.image_ext; } +function getOff(i) { return ratingsL10n.baseimg + (ratingsL10n.custom ? '_' + getRtlI(i) : '') + '_' + getRtlDir('off') + '.' + ratingsL10n.image_ext; } +function getHalf(i) { return ratingsL10n.baseimg + (ratingsL10n.custom ? '_' + getRtlI(i) : '') + '_' + getRtlDir('half') + '.' + ratingsL10n.image_ext; } + +function getRtlDir(name) { + if (!ratingsL10n.rtl) return name; + switch(name) { + case "on": return "off"; + case "off": return "on"; + case "half": return "half-rtl"; + default: return ""; } } -// When User Mouse Out Ratings -function ratings_off(post_id, rating_score, insert_half, half_rtl) { - var element; +/* DOM function: let help knowing whether we are in Ajax mode or not + * Ajax mode: submit async on click + * Non-ajax mode: click stores in an hidden field (value can be changed with further click) and + and it's not wp-postraings responsibility to post the value */ +function is_using_ajax($element, post_id) { + return $element.parent().siblings('input[name="wp_postrating_form_value_' + post_id + '"]').length == 0; +} - if (! ratingsL10n.ajax_url) { - element = $j('input[name="wp_postrating_form_value_' + post_id + '"]'); - // mouseout, but a value was click/selected in order to be later POSTed: do nothing - if (parseInt($j(element).val())) { - return; - } +function non_ajax_hidden_parent($element, post_id) { + var parent = $element.parent().siblings('input[name="wp_postrating_form_value_' + post_id + '"]'); + if (parent.length == 1) return parent; + return false; +} + +// mouseover/out handler +function current_rating(event) { + var post_ratings_el = $j(event.target); + var post_id = $j(event.target).data('id'); + var current_rating = $j(event.target).data('currentRating'); + var rating_score = $j(event.target).data('votes'); + var insert_half = $j(event.target).data('half'); + + if (is_being_rated) return; + + var curval = NaN; // possible stored value: disabled + if (! is_using_ajax(post_ratings_el, post_id)) { + var $parent = non_ajax_hidden_parent(post_ratings_el, post_id); + curval = parseInt($parent.val()); + console.log("foooo", $parent, curval); } - if(!is_being_rated) { - var baseimg = ratingsL10n.plugin_url + '/images/' + ratingsL10n.image + '/rating' ; - for(var i = 1; i <= ratingsL10n.max; i++) { - element = document.getElementById('rating_' + post_id + '_' + i); - if(i <= rating_score) { - element.src = baseimg + (ratingsL10n.custom ? '_' + i : '') + '_on.' + ratingsL10n.image_ext; - } else if(i == insert_half) { - element.src = baseimg + (ratingsL10n.custom ? '_' + i : '') + '_half' + (half_rtl ? '-rtl' : '') + '.' + ratingsL10n.image_ext; - } else { - element.src = baseimg + (ratingsL10n.custom ? '_' + i : '') + '_off.' + ratingsL10n.image_ext; - } - } - if(jQuery('#ratings_' + post_id + '_text').length) { - jQuery('#ratings_' + post_id + '_text').hide().empty(); - } + /* This could be: + 1) first set all OFF + 2) then set to ON those that need + 3) halve it if necessary + 4) then highlight if it's a non-mouseover selection (non-ajax mode) + (currently stored value)... but prioritize mouseover => Math.min(mouseover,selected value) + 5) then highlight up to the score of the current star (if mouseover) + + Make all these passes filling up the array of images URL */ + + var next_images = []; + function setOn(i) { next_images[i] = getOn(i); } + function setOff(i) { next_images[i] = getOff(i); } + function setHalf(i) { next_images[i] = getHalf(i); } + function setOver(i) { next_images[i] = getOver(i); } + + var i; + // 1) off them all + for(i = 1; i <= ratingsL10n.max; i++) setOff(i); + // 2) on up to current score (always applies except for unvoted items) + for(i = 1; i <= current_rating; i++) setOn(i); + // 3) set the half-star (if it applies) + if (event.type == "mouseover" && insert_half > rating_score) setHalf(insert_half); + // 4) on up to currently voted score (if non-ajax, non-default mode) + if (! isNaN(curval)) { + // ToDo: find another color + if (event.type == "mouseover") for(i = 1; i <= Math.min(curval, rating_score); i++) setOver(i); + else for(i = 1; i <= curval; i++) setOver(i); } + // 5) mouseover + if (event.type == "mouseover") for(i = 1; i <= rating_score; i++) setOver(i); + + // Now apply all these images. + // NB: reversing the array, may be an even simpler way to do RTL + for(i = 1; i <= ratingsL10n.max; i++) $j('#rating_' + post_id + '_' + i).attr('src', next_images[i]); + + updateText($j('#ratings_' + post_id + '_text'), post_ratings_el, event.type == "mouseout"); } -// Set is_being_rated Status -function set_is_being_rated(rated_status) { - is_being_rated = rated_status; +function updateText($text_el, $element, mouseout) { + if ($text_el.length) { + if (mouseout) $text_el.hide().empty(); + else $text_el.html($element.data('ratingsText')).show(); + } } + // Process Post Ratings Success function rate_post_success(post_id, data) { $j('#post-ratings-' + post_id).html(data); @@ -104,21 +146,20 @@ function rate_post_success(post_id, data) { $j('#post-ratings-' + post_id + '-loading').hide(); } if(ratingsL10n.show_fading) { - $j('#post-ratings-' + post_id).fadeTo('def', 1, function () { - set_is_being_rated(false); - }); - } else { - set_is_being_rated(false); + $j('#post-ratings-' + post_id).fadeTo('def', 1); } } // Process Post Ratings -function rate_post(post_id, post_rating) { - var post_ratings_el = $j('#post-ratings-' + post_id); +function rate_post(event) { + var post_ratings_el = $j(event.target); + var post_id = $j(event.target).data('id'); + var post_rating = $j(event.target).data('votes'); + var captcha_response; - if (! ratingsL10n.ajax_url) { - var value_holder = $j('input[name="wp_postrating_form_value_' + post_id + '"]'); + if (! is_using_ajax(post_ratings_el, post_id)) { + var value_holder = non_ajax_hidden_parent(post_ratings_el, post_id); var curval = $j(value_holder).val(); $j(value_holder).val(null); $j('#rating_' + post_id + '_' + curval).trigger('mouseout'); @@ -146,11 +187,11 @@ function rate_post(post_id, post_rating) { } } - if(!is_being_rated) { + if(! is_being_rated) { var post_ratings_nonce = $j(post_ratings_el).data('nonce'); if(typeof post_ratings_nonce == 'undefined' || post_ratings_nonce == null) post_ratings_nonce = $j(post_ratings_el).attr('data-nonce'); - set_is_being_rated(true); + is_being_rated = true; if(ratingsL10n.show_fading) { $j(post_ratings_el).fadeTo('def', 0, function () { if(ratingsL10n.show_loading) { @@ -168,7 +209,8 @@ function rate_post(post_id, post_rating) { url: ratingsL10n.ajax_url, data: 'action=postratings&pid=' + post_id + '&rate=' + post_rating + '&postratings_' + post_id + '_nonce=' + post_ratings_nonce + '&g-recaptcha-response=' + captcha_response, cache: false}) - .done(function(data) { rate_post_success(post_id, data); }); + .done(function(data) { rate_post_success(post_id, data); }) + .always(function() { is_being_rated = false; }); } else { diff --git a/wp-postratings.php b/wp-postratings.php index aca8e30..a50d713 100644 --- a/wp-postratings.php +++ b/wp-postratings.php @@ -132,15 +132,25 @@ function get_the_ratings($start_tag = 'div', $custom_id = 0, $ajax) { return "<$start_tag $attributes>".the_ratings_results($ratings_id, 0, 0, 0, 1).''.$loading; // If User Has Not Voted } else { - ratings_script_config($ajax); $html_string = ''; + + /* ATM, the presence of this input#[name="wp_postrating_form_value_' + ratings_id] is the only way + we check whether the value must be submit immediatly through Ajax or not. + In the later case, serves as a value holder of the selected value. + See non_ajax_hidden_parent() and is_using_ajax() inside postratings-js.dev.js */ if (! $ajax) { $html_string .= '' . "\n"; } if ( recaptcha_is_enabled() && recaptcha_is_op() ) { $html_string .= '
'; } - return $html_string . "<$start_tag $attributes data-nonce=\"".wp_create_nonce('postratings_'.$ratings_id.'-nonce')."\">".the_ratings_vote($ratings_id).''.$loading; + return $html_string + . "<$start_tag $attributes data-nonce=\"" + . wp_create_nonce('postratings_'.$ratings_id.'-nonce').'"' + // . ($ajax ? ' data-ajax="1"' ; '') // here if we want to avoid looking to parent's sibling (from PoV, cf JS) + . ">" + . the_ratings_vote($ratings_id, array('ajax' => $ajax)) + . ''.$loading; } } @@ -167,7 +177,18 @@ function the_ratings_results( $post_id, $new_user = 0, $new_score = 0, $new_aver ### Function: Display Ratings Vote -function the_ratings_vote($post_id, $new_user = 0, $new_score = 0, $new_average = 0) { +/** + * @parameter options: an array of templating/rendering option. Known options are: + * - new_user: default 0 + * - new_score: default 0 + * - new_average: default 0 + * - ajax: default: true, whether or not vote should be submited directly (albeigh async) via Ajax or not + * (futur use, not implemented yet) + */ +function the_ratings_vote($post_id, $options) { + $options += array('new_user' => 0, 'new_score' => 0, 'new_average' => 0, 'ajax' => true); + extract($options); // import elements as variable in function scope + if($new_user == 0 && $new_score == 0 && $new_average == 0) { $post_ratings_data = null; } else { @@ -1023,22 +1044,15 @@ function get_ratings_images_vote($post_id, $ratings_custom, $ratings_max, $post_ 'data-id' => $post_id, 'data-votes' => $i, 'data-ratings-text' => $ratings_text, - 'onmouseover' => esc_js( sprintf( "current_rating(%d, %d);", $post_id, $i) ), - 'onclick' => sprintf( "rate_post(%d, %d);", $post_id, $i), - 'onkeypress' => sprintf( "rate_post(%d, %d);", $post_id, $i), + 'data-current-rating' => $post_rating, + 'data-half' => $insert_half, 'style' => "cursor:pointer; border:0px;" ); if($ratings_custom) { - $rating_attr += array( - 'src' => get_rating_image_url($ratings_image, $i <= $post_rating ? 'on' : ( $i == $insert_half ? ($use_custom_half_rtl ? 'half-rtl' : 'half') : 'off'), $i); - 'onmouseout' => sprintf("ratings_off(%d, %d, %d, %d);", $post_id, $post_rating, $insert_half, $use_custom_half_rtl), - ); + $rating_attr['src'] = get_rating_image_url($ratings_image, $i <= $post_rating ? 'on' : ( $i == $insert_half ? ( $use_custom_half_rtl ? 'half-rtl' : 'half' ) : 'off' ), $i); } else { - $rating_attr += array( - 'src' => get_rating_image_url($ratings_image, $i <= $post_rating ? 'on' : ( $i == $insert_half ? ($use_half_rtl ? 'half-rtl' : 'half') : 'off') , NULL); - 'onmouseout' => sprintf("ratings_off(%d, %d, %d, %d);", $post_id, $post_rating, $insert_half, $use_half_rtl), - ); + $rating_attr['src'] = get_rating_image_url($ratings_image, $i <= $post_rating ? 'on' : ( $i == $insert_half ? ( $use_half_rtl ? 'half-rtl' : 'half' ) : 'off' ), NULL); } $ratings_images[] = ''; @@ -1271,7 +1285,7 @@ function expand_ratings_template($template, $post_data, $post_ratings_data = nul $ratings_meta = ''; if( $post_ratings_average > 0 ) { $ratings_meta = << +'
From c50e1a1ce708eabe045fc0daa59b68bc7aa7a9e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Droz?= Date: Wed, 30 Aug 2017 19:43:54 -0300 Subject: [PATCH 18/32] According to [documentation](https://codex.wordpress.org/Creating_Tables_with_Plugins) > You must put each field on its own line in your SQL statement. Indeed this is the condition for dbDelta() to work. Current buggy and unique ALTER statement generated: > ALTER TABLE wp_ratings CHANGE COLUMN `rating_id` rating_id INT(11) NOT NULL auto_increment, rating_postid INT(11) NOT NULL, ... With the fix: > ALTER TABLE wp_ratings CHANGE COLUMN `rating_id` rating_id INT(11) NOT NULL auto_increment > ALTER TABLE wp_ratings CHANGE COLUMN `rating_postid` rating_postid INT(11) NOT NULL > ... --- includes/postratings-activation.php | 30 +++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/includes/postratings-activation.php b/includes/postratings-activation.php index 0411b3b..e3f5527 100644 --- a/includes/postratings-activation.php +++ b/includes/postratings-activation.php @@ -37,20 +37,22 @@ function ratings_activate() { $charset_collate = $wpdb->get_charset_collate(); // Create Post Ratings Table - $create_sql = "CREATE TABLE $wpdb->ratings (". - "rating_id INT(11) NOT NULL auto_increment,". - "rating_postid INT(11) NOT NULL ,". - "rating_posttitle TEXT NOT NULL,". - "rating_rating INT(2) NOT NULL ,". - "rating_timestamp VARCHAR(15) NOT NULL ,". - "rating_ip VARCHAR(40) NOT NULL ,". - "rating_host VARCHAR(200) NOT NULL,". - "rating_username VARCHAR(50) NOT NULL,". - "rating_userid int(10) NOT NULL default '0',". - "PRIMARY KEY (rating_id),". - "KEY rating_userid (rating_userid),". - "KEY rating_postid_ip (rating_postid, rating_ip)) ". - "$charset_collate;"; + $create_sql = <<ratings} ( + rating_id INT(11) NOT NULL auto_increment, + rating_postid INT(11) NOT NULL, + rating_posttitle TEXT NOT NULL, + rating_rating INT(2) NOT NULL, + rating_timestamp VARCHAR(15) NOT NULL, + rating_ip VARCHAR(40) NOT NULL, + rating_host VARCHAR(200) NOT NULL, + rating_username VARCHAR(50) NOT NULL, + rating_userid int(10) NOT NULL default '0', + PRIMARY KEY (rating_id), + KEY rating_userid (rating_userid), + KEY rating_postid_ip (rating_postid, rating_ip)) + {$charset_collate}; +EOF; require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); dbDelta( $create_sql ); From 4deb2f9c1c89e8100f5955d677717e500f181710 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Droz?= Date: Sat, 16 Sep 2017 19:36:08 -0300 Subject: [PATCH 19/32] vote from comments: fix a warning (insert_comment hooks may come without being defined --- includes/postratings-comment.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/includes/postratings-comment.php b/includes/postratings-comment.php index 11c8396..39b762a 100644 --- a/includes/postratings-comment.php +++ b/includes/postratings-comment.php @@ -6,8 +6,12 @@ add_filter( 'wp_insert_comment', 'process_ratings_from_comment' ); function process_ratings_from_comment($comment_id) { - $post_id = intval($_POST['comment_post_ID']); - $rate = intval($_POST["wp_postrating_form_value_$post_id"]); + if ( !isset($_POST['comment_post_ID']) || !isset($_POST['wp_postrating_form_value_' . $post_id]) ) { + return; + } + + $post_id = intval($_POST['comment_post_ID']); + $rate = intval($_POST['wp_postrating_form_value_' . $post_id]); if (! $post_id || ! $rate) { // ignored (could be simply a second comment while missing a second vote) return; From ee1405d2a0ada1ae641298759190b359ca3a4a43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Droz?= Date: Mon, 18 Sep 2017 10:04:35 -0300 Subject: [PATCH 20/32] coding standards --- includes/postratings-comment.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/includes/postratings-comment.php b/includes/postratings-comment.php index 39b762a..44b7fdc 100644 --- a/includes/postratings-comment.php +++ b/includes/postratings-comment.php @@ -10,14 +10,14 @@ function process_ratings_from_comment($comment_id) { return; } - $post_id = intval($_POST['comment_post_ID']); - $rate = intval($_POST['wp_postrating_form_value_' . $post_id]); + $post_id = (int)$_POST['comment_post_ID']; + $rate = (int)$_POST['wp_postrating_form_value_' . $post_id]; if (! $post_id || ! $rate) { // ignored (could be simply a second comment while missing a second vote) return; } - $allow_to_vote_with_comment = intval(get_option('postratings_onlyifcomment')); + $allow_to_vote_with_comment = (int)get_option('postratings_onlyifcomment'); if (! $allow_to_vote_with_comment) { return; } From 5957b212f12ffda1cd027cdb71ee968b3a8ef30d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Droz?= Date: Mon, 18 Sep 2017 12:08:48 -0300 Subject: [PATCH 21/32] voting from REST: bugfix --- includes/postratings-comment.php | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/includes/postratings-comment.php b/includes/postratings-comment.php index 44b7fdc..1035898 100644 --- a/includes/postratings-comment.php +++ b/includes/postratings-comment.php @@ -25,7 +25,7 @@ function process_ratings_from_comment($comment_id) { $rate_id = 0; $last_error = ''; process_ratings($post_id, $rate, $rate_id, $last_error); if ($rate_id) { - add_comment_meta( $comment_id, 'postratings_id', $rate_id ); + update_comment_meta( $comment_id, 'postratings_id', $rate_id ); } // if $last_error: ToDo } @@ -76,23 +76,22 @@ function recent_comment_has_vote( $column_name, $comment_id ) { function process_ratings_from_rest_API( WP_Comment $comment, $rate ) { if (! $comment->comment_post_ID || ! $rate) { // ToDo - return; + return NULL; } - $allow_to_vote_with_comment = intval(get_option('postratings_onlyifcomment')); + $allow_to_vote_with_comment = (int)get_option('postratings_onlyifcomment'); if (! $allow_to_vote_with_comment) { - return; + return FALSE; } $rate_id = 0; $last_error = ''; process_ratings($comment->comment_post_ID, $rate, $rate_id, $last_error); - if ($rate_id) { - add_comment_meta( $comment_id, 'postratings_id', $rate_id ); - return true; + if ( $rate_id ) { + $updated = update_comment_meta( $comment->comment_ID, 'postratings_id', $rate_id ); + return $updated; } - elseif ($last_error) { - var_dump($last_error); + elseif ( $last_error ) { return new WP_Error( 'rest_comment_vote_invalid', $last_error, array( 'status' => 403 ) ); } - return false; + return FALSE; } From 7c12329bd51c9c5c12c9d36a965991294279d410 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Droz?= Date: Mon, 18 Sep 2017 15:33:05 -0300 Subject: [PATCH 22/32] rest: do not setcookie() if voting was done through a REST request --- wp-postratings.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wp-postratings.php b/wp-postratings.php index a50d713..11f7e3f 100644 --- a/wp-postratings.php +++ b/wp-postratings.php @@ -641,7 +641,7 @@ function process_ratings($post_id, $rate, &$last_id = NULL, &$last_error = NULL) // Only Create Cookie If User Choose Logging Method 1 Or 3 $postratings_logging_method = intval(get_option('postratings_logging_method')); - if($postratings_logging_method == 1 || $postratings_logging_method == 3) { + if( ( ! defined( 'REST_REQUEST' ) || !REST_REQUEST ) && ( $postratings_logging_method == 1 || $postratings_logging_method == 3 ) ) { $rate_cookie = setcookie("rated_" . $post_id, $ratings_value[$rate-1], apply_filters('wp_postratings_cookie_expiration', (time() + 30000000) ), From 468847f308269747f956b0a22b4b880e83918014 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Droz?= Date: Mon, 18 Sep 2017 16:31:41 -0300 Subject: [PATCH 23/32] process_ratings: move the HTML return + cookie away from the internal storage function --- wp-postratings.php | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/wp-postratings.php b/wp-postratings.php index 11f7e3f..b4aec6c 100644 --- a/wp-postratings.php +++ b/wp-postratings.php @@ -564,9 +564,28 @@ function process_ratings_from_ajax() { printf($last_error); exit(); } + + // defines $post_ratings_users, $post_ratings_score and $post_ratings_average, $post_ratings_rating + extract($ret); + process_ratings_setcookie($post_id, $post_ratings_rating); + // Output AJAX Result + print ( the_ratings_results($post_id, $post_ratings_users, $post_ratings_score, $post_ratings_average) ); + exit(); } // End if(isset($_REQUEST['action']) && $_REQUEST['action'] == 'postratings') } +function process_ratings_setcookie($post_id, $post_ratings_rating) { + // Only Create Cookie If User Choose Logging Method 1 Or 3 + $postratings_logging_method = (int)get_option('postratings_logging_method'); + if( $postratings_logging_method == 1 || $postratings_logging_method == 3 ) { + return setcookie("rated_" . $post_id, + $post_ratings_rating, + apply_filters('wp_postratings_cookie_expiration', (time() + 30000000) ), + apply_filters('wp_postratings_cookiepath', SITECOOKIEPATH)); + } + return TRUE; +} + // integer $last_id: in/out, if given, fill it with the rate ID inserted inside the DB function process_ratings($post_id, $rate, &$last_id = NULL, &$last_error = NULL) { global $wpdb, $user_identity, $user_ID; @@ -606,7 +625,7 @@ function process_ratings($post_id, $rate, &$last_id = NULL, &$last_error = NULL) if (recaptcha_is_enabled() && recaptcha_is_op() && ! is_human()) { if (! is_null($last_error)) - $last_error = sprintf(esc_html__('invalid captcha.', 'wp-postratings')); + $last_error = esc_html__('invalid captcha.', 'wp-postratings'); return FALSE; } @@ -621,6 +640,7 @@ function process_ratings($post_id, $rate, &$last_id = NULL, &$last_error = NULL) if($rate < 1 || $rate > $ratings_max) { $rate = 0; } + $post_ratings_rating = (int)$ratings_value[$rate-1]; $post_ratings_users = ($post_ratings_users+1); $post_ratings_score = ($post_ratings_score+intval($ratings_value[$rate-1])); $post_ratings_average = round($post_ratings_score/$post_ratings_users, 2); @@ -639,15 +659,6 @@ function process_ratings($post_id, $rate, &$last_id = NULL, &$last_error = NULL) $rate_user = apply_filters( 'wp_postratings_process_ratings_user', $rate_user ); $rate_userid = apply_filters( 'wp_postratings_process_ratings_userid', intval( $user_ID ) ); - // Only Create Cookie If User Choose Logging Method 1 Or 3 - $postratings_logging_method = intval(get_option('postratings_logging_method')); - if( ( ! defined( 'REST_REQUEST' ) || !REST_REQUEST ) && ( $postratings_logging_method == 1 || $postratings_logging_method == 3 ) ) { - $rate_cookie = setcookie("rated_" . $post_id, - $ratings_value[$rate-1], - apply_filters('wp_postratings_cookie_expiration', (time() + 30000000) ), - apply_filters('wp_postratings_cookiepath', SITECOOKIEPATH)); - } - // Log Ratings No Matter What $rate_log = $wpdb->insert( $wpdb->prefix . "ratings", array(// 'rating_id' => 0, autoinc @@ -664,9 +675,7 @@ function process_ratings($post_id, $rate, &$last_id = NULL, &$last_error = NULL) $last_id = $wpdb->insert_id; // Allow Other Plugins To Hook When A Post Is Rated do_action('rate_post', $rate_userid, $post_id, $ratings_value[$rate-1]); - // Output AJAX Result - return the_ratings_results($post_id, $post_ratings_users, $post_ratings_score, $post_ratings_average); - + return compact( "post_ratings_users", "post_ratings_score", "post_ratings_average", "post_ratings_rating"); } From 75cc65c520ae78a811a1a1e2ee49765a36470413 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Droz?= Date: Mon, 18 Sep 2017 23:33:37 -0300 Subject: [PATCH 24/32] simple-quotes around strings --- wp-postratings.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wp-postratings.php b/wp-postratings.php index b4aec6c..040b6f7 100644 --- a/wp-postratings.php +++ b/wp-postratings.php @@ -660,7 +660,7 @@ function process_ratings($post_id, $rate, &$last_id = NULL, &$last_error = NULL) $rate_userid = apply_filters( 'wp_postratings_process_ratings_userid', intval( $user_ID ) ); // Log Ratings No Matter What - $rate_log = $wpdb->insert( $wpdb->prefix . "ratings", + $rate_log = $wpdb->insert( $wpdb->prefix . 'ratings', array(// 'rating_id' => 0, autoinc 'rating_postid' => $post_id, 'rating_posttitle' => $post->post_title, @@ -675,7 +675,7 @@ function process_ratings($post_id, $rate, &$last_id = NULL, &$last_error = NULL) $last_id = $wpdb->insert_id; // Allow Other Plugins To Hook When A Post Is Rated do_action('rate_post', $rate_userid, $post_id, $ratings_value[$rate-1]); - return compact( "post_ratings_users", "post_ratings_score", "post_ratings_average", "post_ratings_rating"); + return compact( 'post_ratings_users', 'post_ratings_score', 'post_ratings_average', 'post_ratings_rating'); } From 417c41de6a21789a57261724008d2eeae1cdbe69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Droz?= Date: Mon, 18 Sep 2017 23:34:22 -0300 Subject: [PATCH 25/32] rest: REST handler (here an update-callback), must either return a value or an WP_Error() --- includes/postratings-comment.php | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/includes/postratings-comment.php b/includes/postratings-comment.php index 1035898..8f78a69 100644 --- a/includes/postratings-comment.php +++ b/includes/postratings-comment.php @@ -74,14 +74,14 @@ function recent_comment_has_vote( $column_name, $comment_id ) { // REST API specific // to be called from the "update_callback" of register_rest_field() function process_ratings_from_rest_API( WP_Comment $comment, $rate ) { + // see update_additional_fields_for_object() if (! $comment->comment_post_ID || ! $rate) { - // ToDo - return NULL; + return new WP_Error( 'rest_comment_vote_invalid', 'Voted content not found.', array( 'status' => 500 ) ); } $allow_to_vote_with_comment = (int)get_option('postratings_onlyifcomment'); if (! $allow_to_vote_with_comment) { - return FALSE; + return new WP_Error( 'rest_comment_vote_invalid', 'Vote bound to comment are not allowed.', array( 'status' => 400 ) ); } $rate_id = 0; $last_error = ''; @@ -90,8 +90,9 @@ function process_ratings_from_rest_API( WP_Comment $comment, $rate ) { $updated = update_comment_meta( $comment->comment_ID, 'postratings_id', $rate_id ); return $updated; } - elseif ( $last_error ) { + + if ( $last_error ) { return new WP_Error( 'rest_comment_vote_invalid', $last_error, array( 'status' => 403 ) ); } - return FALSE; + return new WP_Error( 'rest_comment_vote_invalid', 'Unknown error.', array( 'status' => 500 ) ); } From 495a8dff0ec391c51fca83f3f18468a6f18ba133 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Droz?= Date: Tue, 24 Oct 2017 23:21:10 -0300 Subject: [PATCH 26/32] reduce further js and php templates complexities --- js/postratings-js.dev.js | 30 ++++++------- js/postratings-js.js | 2 +- js/postratings-render-js.dev.js | 34 ++++----------- wp-postratings.php | 77 ++++++++++++++++++--------------- 4 files changed, 66 insertions(+), 77 deletions(-) diff --git a/js/postratings-js.dev.js b/js/postratings-js.dev.js index b097c2d..b2a00fc 100644 --- a/js/postratings-js.dev.js +++ b/js/postratings-js.dev.js @@ -65,12 +65,12 @@ function getRtlDir(name) { * Ajax mode: submit async on click * Non-ajax mode: click stores in an hidden field (value can be changed with further click) and and it's not wp-postraings responsibility to post the value */ -function is_using_ajax($element, post_id) { - return $element.parent().siblings('input[name="wp_postrating_form_value_' + post_id + '"]').length == 0; +function is_using_ajax(post_id) { + return Boolean( $j('#post-ratings-' + post_id).data('ajax') ); } -function non_ajax_hidden_parent($element, post_id) { - var parent = $element.parent().siblings('input[name="wp_postrating_form_value_' + post_id + '"]'); +function non_ajax_hidden_parent(post_id) { + var parent = $j('input[name="wp_postrating_form_value_' + post_id + '"]'); if (parent.length == 1) return parent; return false; } @@ -86,10 +86,9 @@ function current_rating(event) { if (is_being_rated) return; var curval = NaN; // possible stored value: disabled - if (! is_using_ajax(post_ratings_el, post_id)) { - var $parent = non_ajax_hidden_parent(post_ratings_el, post_id); + if (! is_using_ajax(post_id)) { + var $parent = non_ajax_hidden_parent(post_id); curval = parseInt($parent.val()); - console.log("foooo", $parent, curval); } /* This could be: @@ -107,14 +106,15 @@ function current_rating(event) { function setOff(i) { next_images[i] = getOff(i); } function setHalf(i) { next_images[i] = getHalf(i); } function setOver(i) { next_images[i] = getOver(i); } + var max = ratingsL10n.max; var i; // 1) off them all - for(i = 1; i <= ratingsL10n.max; i++) setOff(i); + for(i = 1; i <= max; i++) setOff(i); // 2) on up to current score (always applies except for unvoted items) for(i = 1; i <= current_rating; i++) setOn(i); // 3) set the half-star (if it applies) - if (event.type == "mouseover" && insert_half > rating_score) setHalf(insert_half); + if (insert_half > rating_score) setHalf(insert_half); // 4) on up to currently voted score (if non-ajax, non-default mode) if (! isNaN(curval)) { // ToDo: find another color @@ -126,7 +126,7 @@ function current_rating(event) { // Now apply all these images. // NB: reversing the array, may be an even simpler way to do RTL - for(i = 1; i <= ratingsL10n.max; i++) $j('#rating_' + post_id + '_' + i).attr('src', next_images[i]); + for(i = 1; i <= max; i++) $j('#rating_' + post_id + '_' + i).attr('src', next_images[i]); updateText($j('#ratings_' + post_id + '_text'), post_ratings_el, event.type == "mouseout"); } @@ -156,10 +156,10 @@ function rate_post(event) { var post_id = $j(event.target).data('id'); var post_rating = $j(event.target).data('votes'); - var captcha_response; + var captcha_response = ''; - if (! is_using_ajax(post_ratings_el, post_id)) { - var value_holder = non_ajax_hidden_parent(post_ratings_el, post_id); + if (! is_using_ajax(post_id)) { + var value_holder = non_ajax_hidden_parent(post_id); var curval = $j(value_holder).val(); $j(value_holder).val(null); $j('#rating_' + post_id + '_' + curval).trigger('mouseout'); @@ -188,9 +188,7 @@ function rate_post(event) { } if(! is_being_rated) { - var post_ratings_nonce = $j(post_ratings_el).data('nonce'); - if(typeof post_ratings_nonce == 'undefined' || post_ratings_nonce == null) - post_ratings_nonce = $j(post_ratings_el).attr('data-nonce'); + var post_ratings_nonce = $j(post_ratings_el).parent('.post-ratings').data('nonce'); is_being_rated = true; if(ratingsL10n.show_fading) { $j(post_ratings_el).fadeTo('def', 0, function () { diff --git a/js/postratings-js.js b/js/postratings-js.js index 781c1b5..937f531 100644 --- a/js/postratings-js.js +++ b/js/postratings-js.js @@ -1 +1 @@ -function current_rating(t,a){if(!ratingsL10n.ajax_url){var n=$j('input[name="wp_postrating_form_value_'+t+'"]');if(parseInt($j(n).val()))return}if(!is_being_rated){if(ratingsL10n.custom&&2==ratingsL10n.max)document.getElementById("rating_"+t+"_"+a).src=ratings_mouseover_image[r].src;else for(var r=1;r<=a;r++)document.getElementById("rating_"+t+"_"+r).src=ratingsL10n.custom?ratings_mouseover_image[r].src:ratings_mouseover_image.src;jQuery("#ratings_"+t+"_text").length&&jQuery("#ratings_"+t+"_text").html(jQuery("#rating_"+t+"_"+a).data("ratingsText")).show()}}function ratings_off(t,a,n,r){var e;if((ratingsL10n.ajax_url||(e=$j('input[name="wp_postrating_form_value_'+t+'"]'),!parseInt($j(e).val())))&&!is_being_rated){for(var i=ratingsL10n.plugin_url+"/images/"+ratingsL10n.image+"/rating",s=1;s<=ratingsL10n.max;s++)e=document.getElementById("rating_"+t+"_"+s),s<=a?e.src=i+(ratingsL10n.custom?"_"+s:"")+"_on."+ratingsL10n.image_ext:s==n?e.src=i+(ratingsL10n.custom?"_"+s:"")+"_half"+(r?"-rtl":"")+"."+ratingsL10n.image_ext:e.src=i+(ratingsL10n.custom?"_"+s:"")+"_off."+ratingsL10n.image_ext;jQuery("#ratings_"+t+"_text").length&&jQuery("#ratings_"+t+"_text").hide().empty()}}function set_is_being_rated(t){is_being_rated=t}function rate_post_success(t,a){$j("#post-ratings-"+t).html(a),ratingsL10n.show_loading&&$j("#post-ratings-"+t+"-loading").hide(),ratingsL10n.show_fading?$j("#post-ratings-"+t).fadeTo("def",1,function(){set_is_being_rated(!1)}):set_is_being_rated(!1)}function rate_post(t,a){var n,r=$j("#post-ratings-"+t);if(!ratingsL10n.ajax_url){var e=$j('input[name="wp_postrating_form_value_'+t+'"]'),i=$j(e).val();return $j(e).val(null),$j("#rating_"+t+"_"+i).trigger("mouseout"),void(i!=a&&($j("#rating_"+t+"_"+a).trigger("mouseover"),$j(e).val(a)))}if(ratingsL10n.captcha_sitekey&&ratingsL10n.captcha_sitekey.length){if(null===postratings_captcha)return void(postratings_captcha=grecaptcha.render("g-recaptcha-response",{sitekey:ratingsL10n.captcha_sitekey}));if(n=grecaptcha.getResponse(postratings_captcha),!grecaptcha.getResponse(postratings_captcha))return;$j("#g-recaptcha-response").remove()}if(is_being_rated)alert(ratingsL10n.text_wait);else{var s=$j(r).data("nonce");"undefined"!=typeof s&&null!=s||(s=$j(r).attr("data-nonce")),set_is_being_rated(!0),ratingsL10n.show_fading?$j(r).fadeTo("def",0,function(){ratingsL10n.show_loading&&$j("#post-ratings-"+t+"-loading").show()}):ratingsL10n.show_loading&&$j("#post-ratings-"+t+"-loading").show(),$j.post({xhrFields:{withCredentials:!0},dataType:"html",url:ratingsL10n.ajax_url,data:"action=postratings&pid="+t+"&rate="+a+"&postratings_"+t+"_nonce="+s+"&g-recaptcha-response="+n,cache:!1}).done(function(a){rate_post_success(t,a)})}}var $j=jQuery.noConflict(),is_being_rated=!1,postratings_captcha=null;ratingsL10n.custom=parseInt(ratingsL10n.custom),ratingsL10n.max=parseInt(ratingsL10n.max),ratingsL10n.show_loading=parseInt(ratingsL10n.show_loading),ratingsL10n.show_fading=parseInt(ratingsL10n.show_fading);var ratings_mouseover_image;if(ratingsL10n.custom){ratings_mouseover_image=[];for(var i=1;i<=ratingsL10n.max;i++)ratings_mouseover_image[i]=new Image,ratings_mouseover_image[i].src=ratingsL10n.plugin_url+"/images/"+ratingsL10n.image+"/rating_"+i+"_over."+ratingsL10n.image_ext}else ratings_mouseover_image=new Image,ratings_mouseover_image.src=ratingsL10n.plugin_url+"/images/"+ratingsL10n.image+"/rating_over."+ratingsL10n.image_ext; \ No newline at end of file +var $j=jQuery.noConflict();var is_being_rated=false;var postratings_captcha=null;var ratings_mouseover_image;jQuery(function($){ratingsL10n.custom=parseInt(ratingsL10n.custom);ratingsL10n.max=parseInt(ratingsL10n.max);ratingsL10n.show_loading=parseInt(ratingsL10n.show_loading);ratingsL10n.show_fading=parseInt(ratingsL10n.show_fading);ratingsL10n.baseimg=ratingsL10n.plugin_url+"/images/"+ratingsL10n.image+"/rating";ratingsL10n.rtl=parseInt(ratingsL10n.rtl);if(ratingsL10n.custom){ratings_mouseover_image=[];for(var i=1;i<=ratingsL10n.max;i++){ratings_mouseover_image[i]=new Image;ratings_mouseover_image[i].src=ratingsL10n.baseimg+"_"+i+"_over."+ratingsL10n.image_ext}}else{ratings_mouseover_image=new Image;ratings_mouseover_image.src=ratingsL10n.baseimg+"_over."+ratingsL10n.image_ext}$("img[data-votes]").on("mouseover mouseout",current_rating).on("click keypress",rate_post)});function getRtlI(i){return!ratingsL10n.rtl?i:ratingsL10n.max-i+1}function getOver(i){return ratingsL10n.custom?ratings_mouseover_image[getRtlI(i)].src:ratings_mouseover_image.src}function getOn(i){return ratingsL10n.baseimg+(ratingsL10n.custom?"_"+getRtlI(i):"")+"_"+getRtlDir("on")+"."+ratingsL10n.image_ext}function getOff(i){return ratingsL10n.baseimg+(ratingsL10n.custom?"_"+getRtlI(i):"")+"_"+getRtlDir("off")+"."+ratingsL10n.image_ext}function getHalf(i){return ratingsL10n.baseimg+(ratingsL10n.custom?"_"+getRtlI(i):"")+"_"+getRtlDir("half")+"."+ratingsL10n.image_ext}function getRtlDir(name){if(!ratingsL10n.rtl)return name;switch(name){case"on":return"off";case"off":return"on";case"half":return"half-rtl";default:return""}}function is_using_ajax(post_id){return Boolean($j("#post-ratings-"+post_id).data("ajax"))}function non_ajax_hidden_parent(post_id){var parent=$j('input[name="wp_postrating_form_value_'+post_id+'"]');if(parent.length==1)return parent;return false}function current_rating(event){var post_ratings_el=$j(event.target);var post_id=$j(event.target).data("id");var current_rating=$j(event.target).data("currentRating");var rating_score=$j(event.target).data("votes");var insert_half=$j(event.target).data("half");if(is_being_rated)return;var curval=NaN;if(!is_using_ajax(post_id)){var $parent=non_ajax_hidden_parent(post_id);curval=parseInt($parent.val())}var next_images=[];function setOn(i){next_images[i]=getOn(i)}function setOff(i){next_images[i]=getOff(i)}function setHalf(i){next_images[i]=getHalf(i)}function setOver(i){next_images[i]=getOver(i)}var max=ratingsL10n.max;var i;for(i=1;i<=max;i++)setOff(i);for(i=1;i<=current_rating;i++)setOn(i);if(insert_half>rating_score)setHalf(insert_half);if(!isNaN(curval)){if(event.type=="mouseover")for(i=1;i<=Math.min(curval,rating_score);i++)setOver(i);else for(i=1;i<=curval;i++)setOver(i)}if(event.type=="mouseover")for(i=1;i<=rating_score;i++)setOver(i);for(i=1;i<=max;i++)$j("#rating_"+post_id+"_"+i).attr("src",next_images[i]);updateText($j("#ratings_"+post_id+"_text"),post_ratings_el,event.type=="mouseout")}function updateText($text_el,$element,mouseout){if($text_el.length){if(mouseout)$text_el.hide().empty();else $text_el.html($element.data("ratingsText")).show()}}function rate_post_success(post_id,data){$j("#post-ratings-"+post_id).html(data);if(ratingsL10n.show_loading){$j("#post-ratings-"+post_id+"-loading").hide()}if(ratingsL10n.show_fading){$j("#post-ratings-"+post_id).fadeTo("def",1)}}function rate_post(event){var post_ratings_el=$j(event.target);var post_id=$j(event.target).data("id");var post_rating=$j(event.target).data("votes");var captcha_response="";if(!is_using_ajax(post_id)){var value_holder=non_ajax_hidden_parent(post_id);var curval=$j(value_holder).val();$j(value_holder).val(null);$j("#rating_"+post_id+"_"+curval).trigger("mouseout");if(curval!=post_rating){$j("#rating_"+post_id+"_"+post_rating).trigger("mouseover");$j(value_holder).val(post_rating)}return}if(ratingsL10n.captcha_sitekey&&ratingsL10n.captcha_sitekey.length){if(postratings_captcha===null){postratings_captcha=grecaptcha.render("g-recaptcha-response",{sitekey:ratingsL10n.captcha_sitekey});return}else{captcha_response=grecaptcha.getResponse(postratings_captcha);if(!grecaptcha.getResponse(postratings_captcha)){return}else{$j("#g-recaptcha-response").remove()}}}if(!is_being_rated){var post_ratings_nonce=$j(post_ratings_el).parent(".post-ratings").data("nonce");is_being_rated=true;if(ratingsL10n.show_fading){$j(post_ratings_el).fadeTo("def",0,function(){if(ratingsL10n.show_loading){$j("#post-ratings-"+post_id+"-loading").show()}})}else{if(ratingsL10n.show_loading){$j("#post-ratings-"+post_id+"-loading").show()}}$j.post({xhrFields:{withCredentials:true},dataType:"html",url:ratingsL10n.ajax_url,data:"action=postratings&pid="+post_id+"&rate="+post_rating+"&postratings_"+post_id+"_nonce="+post_ratings_nonce+"&g-recaptcha-response="+captcha_response,cache:false}).done(function(data){rate_post_success(post_id,data)}).always(function(){is_being_rated=false})}else{alert(ratingsL10n.text_wait)}} \ No newline at end of file diff --git a/js/postratings-render-js.dev.js b/js/postratings-render-js.dev.js index e6555b9..e9e6db1 100644 --- a/js/postratings-render-js.dev.js +++ b/js/postratings-render-js.dev.js @@ -28,34 +28,16 @@ function expand_ratings_template(rating, max_rate, images_dir) { var img_dir = images_dir || wp_postratings.images_dir; var img; - var ratings_images = ''; var vote_text = rating.usr > 1 ? 'votes' : 'vote'; var alt_text = rating.usr + ' ' + vote_text + ', average: ' + rating.avg; - for (var i=1; i<= max_rate; i++) { - if (i <= Math.round(rating.avg, 1)) { - img = "on"; - } else if(i == _get_voting_half_star(rating.avg)) { - img = "half"; - } else { - img = "off"; - } - ratings_images += '' + alt_text + ''; - } + var tpl = `${alt_text}\n`; + // templating + var ratings_images = '', i = 1; + var has_half = Math.abs(rating.avg - Math.floor(rating.avg)).toFixed(3) >= 0.25; + for (i=1; i<= Math.floor(rating.avg); i++) ratings_images += tpl.replace(/%s/g,"on"); + if (i < max_rate) ratings_images += tpl.replace(/%s/g, has_half ? 'half' : 'off'); + for (++i; i <= max_rate; i++) ratings_images += tpl.replace(/%s/g,"off"); + // return return ratings_images + ' (' + rating.usr + ' ' + vote_text + ')'; } - -// helper for expand_ratings_template() -function _get_voting_half_star(avg) { - var post_ratings = Math.round(avg, 1); - var post_ratings_average = Math.abs(Math.floor(avg)); - var average_diff = post_ratings_average - post_ratings; - var insert_half = 0; - if (average_diff >= 0.25 && average_diff <= 0.75) { - insert_half = Math.ceil(post_ratings_average); - } - else if (average_diff > 0.75) { - insert_half = Math.ceil(post_ratings); - } - return insert_half; -} diff --git a/wp-postratings.php b/wp-postratings.php index 040b6f7..04c527d 100644 --- a/wp-postratings.php +++ b/wp-postratings.php @@ -104,53 +104,62 @@ function get_the_ratings($start_tag = 'div', $custom_id = 0, $ajax) { $ratings_id = (int) $ratings_id; // Loading Style - $postratings_ajax_style = get_option('postratings_ajax_style'); - if(intval($postratings_ajax_style['loading']) == 1) { - $loading = '<' . $start_tag . ' id="post-ratings-' . $ratings_id . '-loading" class="post-ratings-loading"> - ' . esc_html__( 'Loading...', 'wp-postratings' ) . ''; - } else { - $loading = ''; + $loading = ''; + if(intval(get_option('postratings_ajax_style')) == 1) { + $loading = sprintf(<<<'EOF' +<%1$s id="post-ratings-%2$d-loading" class="post-ratings-loading"> + + %4$s + +EOF + , + $start_tag, + $ratings_id, + plugins_url('wp-postratings/images/loading.gif'), + esc_html__( 'Loading...', 'wp-postratings' ) + ); } - // Check To See Whether User Has Voted - $user_voted = check_rated($ratings_id); + // HTML Attributes - $ratings_options = get_option('postratings_options'); - $ratings_options['richsnippet'] = isset( $ratings_options['richsnippet'] ) ? $ratings_options['richsnippet'] : 1; - if( is_singular() && $ratings_options['richsnippet'] ) { + $richsnippet = get_option('postratings_options', array('richsnippet' => 1)); + $itemtype = ''; + if( is_singular() && $richsnippet ) { $itemtype = apply_filters('wp_postratings_schema_itemtype', 'itemscope itemtype="http://schema.org/Article"'); - $attributes = 'id="post-ratings-'.$ratings_id.'" class="post-ratings" '.$itemtype; - } else { - $attributes = 'id="post-ratings-'.$ratings_id.'" class="post-ratings"'; } - // If User Voted Or Is Not Allowed To Rate - if($user_voted) { - return "<$start_tag $attributes>".the_ratings_results($ratings_id).''.$loading; + $template = '<%1$s id="post-ratings-%2$d" class="post-ratings" %3$s> %4$s %5$s'; + + // Check To See Whether User Has Voted + if ( check_rated($ratings_id) ) { + return sprintf($template, $start_tag, $ratings_id, $itemtype, the_ratings_results($ratings_id), $loading); // If User Is Not Allowed To Rate - } else if(!check_allowtorate()) { - return "<$start_tag $attributes>".the_ratings_results($ratings_id, 0, 0, 0, 1).''.$loading; + } else if( !check_allowtorate() ) { + return sprintf($template, $start_tag, $ratings_id, $itemtype, the_ratings_results($ratings_id, 0, 0, 0, 1), $loading); // If User Has Not Voted } else { - $html_string = ''; - /* ATM, the presence of this input#[name="wp_postrating_form_value_' + ratings_id] is the only way we check whether the value must be submit immediatly through Ajax or not. In the later case, serves as a value holder of the selected value. See non_ajax_hidden_parent() and is_using_ajax() inside postratings-js.dev.js */ - if (! $ajax) { - $html_string .= '' . "\n"; - } - if ( recaptcha_is_enabled() && recaptcha_is_op() ) { - $html_string .= '
'; - } - return $html_string - . "<$start_tag $attributes data-nonce=\"" - . wp_create_nonce('postratings_'.$ratings_id.'-nonce').'"' - // . ($ajax ? ' data-ajax="1"' ; '') // here if we want to avoid looking to parent's sibling (from PoV, cf JS) - . ">" - . the_ratings_vote($ratings_id, array('ajax' => $ajax)) - . ''.$loading; + + return sprintf(<<<'EOF' +
+<%1$s id="post-ratings-%2$d" class="post-ratings" %3$s data-nonce="%4$s" data-ajax="%5$d"> + + %6$s + +%7$s +EOF + , + $start_tag, + $ratings_id, + $itemtype, // $3 + wp_create_nonce('postratings_'.$ratings_id.'-nonce'), + $ajax, // $5: here if we want to avoid looking to parent's sibling (from PoV, cf JS) + the_ratings_vote($ratings_id, array('ajax' => $ajax)), + $loading // $7 + ); } } From 1131caee89e89ac76cf7e2446e5746c044f226ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Droz?= Date: Tue, 24 Oct 2017 23:21:39 -0300 Subject: [PATCH 27/32] spurious quote --- wp-postratings.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wp-postratings.php b/wp-postratings.php index 04c527d..7ab7dff 100644 --- a/wp-postratings.php +++ b/wp-postratings.php @@ -1303,7 +1303,7 @@ function expand_ratings_template($template, $post_data, $post_ratings_data = nul $ratings_meta = ''; if( $post_ratings_average > 0 ) { $ratings_meta = << +
From c0c127235bd1fed95273ca858a0fa5a9bf7fa65b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Droz?= Date: Thu, 2 Nov 2017 20:40:23 -0300 Subject: [PATCH 28/32] Much more flexible way to hook into the validation process (at the price of wp_postratings_check_rated()). It should now be possible to conditionnally enable/disable validation method according to the way the rate was submitted (comment/ajax/REST API/...) --- includes/validation.php | 135 ++++++++++++++++++++++++++++++++++++++++ wp-postratings.php | 135 +++------------------------------------- 2 files changed, 144 insertions(+), 126 deletions(-) create mode 100644 includes/validation.php diff --git a/includes/validation.php b/includes/validation.php new file mode 100644 index 0000000..2951b25 --- /dev/null +++ b/includes/validation.php @@ -0,0 +1,135 @@ + 0; +} + +// Check Rated By Cookie +function wpr_check_rated_cookie( $err, $post_id ) { + $rated = isset($_COOKIE["rated_$post_id"]); + if ( $rated ) { + $err[] = sprintf(esc_html__('You already rated post #%d (cookie).', 'wp-postratings'), $post_id); + } + return $err; +} + + +// Check Rated By IP +function wpr_check_rated_ip( $err, $post_id ) { + global $wpdb; + // Check IP From IP Logging Database + if ($wpdb->get_var( $wpdb->prepare( "SELECT rating_ip FROM {$wpdb->ratings} WHERE rating_postid = %d AND rating_ip = %s", $post_id, get_ipaddress() ) ) ) { + $err[] = sprintf(esc_html__('You already rated post #%d (ip).', 'wp-postratings'), $post_id); + } + return $err; +} + + +// Check Rated By Username +function wpr_check_rated_username( $err, $post_id ) { + global $wpdb, $user_ID; + if( !is_user_logged_in() ) { + $err[] = sprintf(esc_html__('You already rated post #%d (anonymous userid).', 'wp-postratings'), $post_id); + return $err; + } + + // Check User ID From IP Logging Database + if ( $wpdb->get_var( $wpdb->prepare( "SELECT rating_userid FROM {$wpdb->ratings} WHERE rating_postid = %d AND rating_userid = %d", $post_id, $user_ID ) ) ) { + $err[] = sprintf(esc_html__('You already rated post #%d (userid).', 'wp-postratings'), $post_id); + } + return $err; +} diff --git a/wp-postratings.php b/wp-postratings.php index 7ab7dff..35c2ce7 100644 --- a/wp-postratings.php +++ b/wp-postratings.php @@ -63,6 +63,7 @@ require_once( 'includes/postratings-widgets.php' ); require_once( 'includes/postratings-comment.php' ); require_once( 'includes/postratings-bayesian-score.php' ); +require_once( 'includes/validation.php' ); /** * Register plugin activation hook @@ -75,6 +76,7 @@ function postratings_init() { if( ! defined( 'RATINGS_IMG_EXT' ) ) { define( 'RATINGS_IMG_EXT', apply_filters( 'wp_postratings_image_extension', 'gif' ) ); } + wpr_setup_validation(); } ### Function: Display The Rating For The Post @@ -131,10 +133,10 @@ function get_the_ratings($start_tag = 'div', $custom_id = 0, $ajax) { $template = '<%1$s id="post-ratings-%2$d" class="post-ratings" %3$s> %4$s %5$s'; // Check To See Whether User Has Voted - if ( check_rated($ratings_id) ) { + if ( wpr_has_already_rated( $ratings_id ) ) { return sprintf($template, $start_tag, $ratings_id, $itemtype, the_ratings_results($ratings_id), $loading); // If User Is Not Allowed To Rate - } else if( !check_allowtorate() ) { + } else if( !wpr_is_allowed_to_rate() ) { return sprintf($template, $start_tag, $ratings_id, $itemtype, the_ratings_results($ratings_id, 0, 0, 0, 1), $loading); // If User Has Not Voted } else { @@ -220,94 +222,6 @@ function the_ratings_vote($post_id, $options) { } -### Function: Check Who Is Allow To Rate -function check_allowtorate() { - $allow_to_vote = intval(get_option('postratings_allowtorate')); - switch($allow_to_vote) { - // Guests Only - case 0: - return ! is_user_logged_in(); - // Logged-in users only - case 1: - return is_user_logged_in(); - // Users registered on blog (for multisite) - case 3: - return is_user_member_of_blog(); - // Registered Users And Guests - case 2: - default: - return true; - } -} - - -### Function: Check Whether User Have Rated For The Post -function check_rated( $post_id ) { - $postratings_logging_method = intval( get_option( 'postratings_logging_method' ) ); - $rated = false; - switch( $postratings_logging_method ) { - // Do Not Log - case 0: - $rated = false; - break; - // Logged By Cookie - case 1: - $rated = check_rated_cookie( $post_id ); - break; - // Logged By IP - case 2: - $rated = check_rated_ip( $post_id ); - break; - // Logged By Cookie And IP - case 3: - $rated_cookie = check_rated_cookie( $post_id ); - if( $rated_cookie > 0 ) { - $rated = true; - } else { - $rated = check_rated_ip( $post_id ); - } - break; - // Logged By Username - case 4: - $rated = check_rated_username( $post_id ); - break; - } - - $rated = apply_filters( 'wp_postratings_check_rated', $rated, $post_id ); - - return $rated; -} - - -### Function: Check Rated By Cookie -function check_rated_cookie($post_id) { - return (isset($_COOKIE["rated_$post_id"])); -} - - -### Function: Check Rated By IP -function check_rated_ip($post_id) { - global $wpdb; - // Check IP From IP Logging Database - $get_rated = $wpdb->get_var( $wpdb->prepare( "SELECT rating_ip FROM {$wpdb->ratings} WHERE rating_postid = %d AND rating_ip = %s", $post_id, get_ipaddress() ) ); - // 0: False | > 0: True - return intval($get_rated); -} - - -### Function: Check Rated By Username -function check_rated_username($post_id) { - global $wpdb, $user_ID; - if(!is_user_logged_in()) { - return 0; - } - // Check User ID From IP Logging Database - $get_rated = $wpdb->get_var( $wpdb->prepare( "SELECT rating_userid FROM {$wpdb->ratings} WHERE rating_postid = %d AND rating_userid = %d", $post_id, $user_ID ) ); - // 0: False | > 0: True - return intval( $get_rated); -} - - ### Function: Get Comment Authors Ratings add_action('loop_start', 'get_comment_authors_ratings'); function get_comment_authors_ratings() { @@ -596,48 +510,17 @@ function process_ratings_setcookie($post_id, $post_ratings_rating) { } // integer $last_id: in/out, if given, fill it with the rate ID inserted inside the DB -function process_ratings($post_id, $rate, &$last_id = NULL, &$last_error = NULL) { +function process_ratings( $post_id, $rate, &$last_id = NULL, &$last_error = array() ) { global $wpdb, $user_identity, $user_ID; - if($rate <= 0) { - if (! is_null($last_error)) - $last_error = esc_html__('Invalid rate value.', 'wp-postratings'); - return FALSE; - } - - if (! $post_id) { - if (! is_null($last_error)) - $last_error = sprintf(esc_html__('Invalid Post ID #%d.', 'wp-postratings'), $post_id); - return FALSE; - } - - if (! check_allowtorate()) { - if (! is_null($last_error)) - $last_error = esc_html__('Voting forbidden, check policy.', 'wp-postratings'); + $errors = array(); + $can_rate = apply_filters( 'wp_postratings_can_rate', $errors, $post_id, $rate); + if (! empty($can_rate)) { + $last_error = $can_rate; return FALSE; } - // Check Whether Post Has Been Rated By User - if (check_rated($post_id)) { - if (! is_null($last_error)) - $last_error = sprintf(esc_html__('You already rated post #%d.', 'wp-postratings'), $post_id); - return FALSE; - } - - // Check Whether Is There A Valid Post $post = get_post($post_id); - if (! $post || wp_is_post_revision($post)) { - if (! is_null($last_error)) - $last_error = sprintf(esc_html__('Invalid post #%d.', 'wp-postratings'), $post_id); - return FALSE; - } - - if (recaptcha_is_enabled() && recaptcha_is_op() && ! is_human()) { - if (! is_null($last_error)) - $last_error = esc_html__('invalid captcha.', 'wp-postratings'); - return FALSE; - } - // If Valid Post Then We Rate It $ratings_max = intval(get_option('postratings_max')); $ratings_custom = intval(get_option('postratings_customrating')); From 9a38a3f868e8c849b4259cadf3f49028143cf484 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Droz?= Date: Thu, 9 Nov 2017 23:47:38 -0300 Subject: [PATCH 29/32] Don't hardcode a comment "Rate @" suffixe. Instead, themes may use things like ``` echo str_repeat(sprintf('star', plugins_url( 'wp-postratings/images/stars' ) ), $comment->postrating_rate); ``` --- includes/postratings-comment.php | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/includes/postratings-comment.php b/includes/postratings-comment.php index 8f78a69..44589dc 100644 --- a/includes/postratings-comment.php +++ b/includes/postratings-comment.php @@ -30,25 +30,24 @@ function process_ratings_from_comment($comment_id) { // if $last_error: ToDo } -add_filter( 'comments_array', 'show_rating_in_comment' ); -function show_rating_in_comment($comments) { +add_filter( 'comments_array', 'comments_load_rate' ); +function comments_load_rate($comments) { if( ! count( $comments ) ) return; - global $wpdb; + global $wpdb; foreach( $comments as $comment ) { $rate_id = get_comment_meta($comment->comment_ID, 'postratings_id', true); if (intval($rate_id)) { $rate = $wpdb->get_var( $wpdb->prepare( "SELECT rating_rating FROM {$wpdb->ratings} WHERE rating_id = %d", intval($rate_id)) ); if ($rate) { - $comment->comment_content .= '

' - . esc_html(sprintf(__('Rated %d', 'wp-postratings'), $rate)) - . '

'; + $comment->postrating_rate = $rate; } } } return $comments; } + add_filter( 'manage_edit-comments_columns', 'comment_has_vote' ); function comment_has_vote( $columns ) { $columns['comment-vote'] = __( 'Vote', 'wp-postratings' ); From 70fe66d9449a02a505baac8139fb05ea1768539e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Droz?= Date: Thu, 25 Jan 2018 14:56:17 -0300 Subject: [PATCH 30/32] make js-based voting code more reusable --- js/postratings-js.dev.js | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/js/postratings-js.dev.js b/js/postratings-js.dev.js index b2a00fc..10aba98 100644 --- a/js/postratings-js.dev.js +++ b/js/postratings-js.dev.js @@ -19,7 +19,12 @@ var is_being_rated = false; var postratings_captcha = null; var ratings_mouseover_image; -jQuery(function($) { +jQuery(function() { + postratings_init_vars(); + postratings_setup_evt_listeners(); +}); + +function postratings_init_vars() { ratingsL10n.custom = parseInt(ratingsL10n.custom); ratingsL10n.max = parseInt(ratingsL10n.max); ratingsL10n.show_loading = parseInt(ratingsL10n.show_loading); @@ -37,12 +42,11 @@ jQuery(function($) { ratings_mouseover_image = new Image(); ratings_mouseover_image.src = ratingsL10n.baseimg + "_over." + ratingsL10n.image_ext ; } +}; - $('img[data-votes]') - .on('mouseover mouseout', current_rating) - .on('click keypress', rate_post); - -}); +function postratings_setup_evt_listeners() { + jQuery('img[data-votes]').on('mouseover mouseout', current_rating).on('click keypress', rate_post); +}; // intermediary functions: wrap RTL complexity (invert on/off) function getRtlI(i) { return (!ratingsL10n.rtl) ? i : (ratingsL10n.max - i + 1); } From 91e418fc970948b1d8b0291ff99c66593353c474 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Droz?= Date: Thu, 25 Jan 2018 14:56:43 -0300 Subject: [PATCH 31/32] js-based widget: use native querySelector() function rather than jQuery --- js/postratings-js.dev.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/postratings-js.dev.js b/js/postratings-js.dev.js index 10aba98..efa542d 100644 --- a/js/postratings-js.dev.js +++ b/js/postratings-js.dev.js @@ -130,7 +130,7 @@ function current_rating(event) { // Now apply all these images. // NB: reversing the array, may be an even simpler way to do RTL - for(i = 1; i <= max; i++) $j('#rating_' + post_id + '_' + i).attr('src', next_images[i]); + for(i = 1; i <= max; i++) document.querySelector('img#rating_' + post_id + '_' + i).setAttribute('src', next_images[i]); updateText($j('#ratings_' + post_id + '_text'), post_ratings_el, event.type == "mouseout"); } From 024fffdc4f6abe3efdb8a62916d718788ee1bbeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Droz?= Date: Fri, 9 Feb 2018 22:32:24 -0300 Subject: [PATCH 32/32] don't force rating script inside the footer. Recompress new code --- includes/postratings-scripts.php | 2 +- js/postratings-js.dev.js | 2 +- js/postratings-js.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/includes/postratings-scripts.php b/includes/postratings-scripts.php index 73b18bf..97178b3 100644 --- a/includes/postratings-scripts.php +++ b/includes/postratings-scripts.php @@ -43,7 +43,7 @@ function ratings_scripts() { } } - wp_enqueue_script('wp-postratings', plugins_url('wp-postratings/js/postratings-js.dev.js'), array('jquery'), WP_POSTRATINGS_VERSION, true); + wp_enqueue_script('wp-postratings', plugins_url('wp-postratings/js/postratings-js.dev.js'), array('jquery'), WP_POSTRATINGS_VERSION); // these are static JS parameters $postratings_ajax_style = get_option( 'postratings_ajax_style' ); diff --git a/js/postratings-js.dev.js b/js/postratings-js.dev.js index efa542d..8c7743f 100644 --- a/js/postratings-js.dev.js +++ b/js/postratings-js.dev.js @@ -3,7 +3,7 @@ | | | WordPress Plugin: WP-PostRatings | | Copyright (c) 2012 Lester "GaMerZ" Chan | - | Copyright (c) 2017 Raphaël Droz | + | Copyright (c) 2017, 2018 Raphaël Droz | | | | File Information: | | - Post Ratings Javascript File | diff --git a/js/postratings-js.js b/js/postratings-js.js index 937f531..9cb5695 100644 --- a/js/postratings-js.js +++ b/js/postratings-js.js @@ -1 +1 @@ -var $j=jQuery.noConflict();var is_being_rated=false;var postratings_captcha=null;var ratings_mouseover_image;jQuery(function($){ratingsL10n.custom=parseInt(ratingsL10n.custom);ratingsL10n.max=parseInt(ratingsL10n.max);ratingsL10n.show_loading=parseInt(ratingsL10n.show_loading);ratingsL10n.show_fading=parseInt(ratingsL10n.show_fading);ratingsL10n.baseimg=ratingsL10n.plugin_url+"/images/"+ratingsL10n.image+"/rating";ratingsL10n.rtl=parseInt(ratingsL10n.rtl);if(ratingsL10n.custom){ratings_mouseover_image=[];for(var i=1;i<=ratingsL10n.max;i++){ratings_mouseover_image[i]=new Image;ratings_mouseover_image[i].src=ratingsL10n.baseimg+"_"+i+"_over."+ratingsL10n.image_ext}}else{ratings_mouseover_image=new Image;ratings_mouseover_image.src=ratingsL10n.baseimg+"_over."+ratingsL10n.image_ext}$("img[data-votes]").on("mouseover mouseout",current_rating).on("click keypress",rate_post)});function getRtlI(i){return!ratingsL10n.rtl?i:ratingsL10n.max-i+1}function getOver(i){return ratingsL10n.custom?ratings_mouseover_image[getRtlI(i)].src:ratings_mouseover_image.src}function getOn(i){return ratingsL10n.baseimg+(ratingsL10n.custom?"_"+getRtlI(i):"")+"_"+getRtlDir("on")+"."+ratingsL10n.image_ext}function getOff(i){return ratingsL10n.baseimg+(ratingsL10n.custom?"_"+getRtlI(i):"")+"_"+getRtlDir("off")+"."+ratingsL10n.image_ext}function getHalf(i){return ratingsL10n.baseimg+(ratingsL10n.custom?"_"+getRtlI(i):"")+"_"+getRtlDir("half")+"."+ratingsL10n.image_ext}function getRtlDir(name){if(!ratingsL10n.rtl)return name;switch(name){case"on":return"off";case"off":return"on";case"half":return"half-rtl";default:return""}}function is_using_ajax(post_id){return Boolean($j("#post-ratings-"+post_id).data("ajax"))}function non_ajax_hidden_parent(post_id){var parent=$j('input[name="wp_postrating_form_value_'+post_id+'"]');if(parent.length==1)return parent;return false}function current_rating(event){var post_ratings_el=$j(event.target);var post_id=$j(event.target).data("id");var current_rating=$j(event.target).data("currentRating");var rating_score=$j(event.target).data("votes");var insert_half=$j(event.target).data("half");if(is_being_rated)return;var curval=NaN;if(!is_using_ajax(post_id)){var $parent=non_ajax_hidden_parent(post_id);curval=parseInt($parent.val())}var next_images=[];function setOn(i){next_images[i]=getOn(i)}function setOff(i){next_images[i]=getOff(i)}function setHalf(i){next_images[i]=getHalf(i)}function setOver(i){next_images[i]=getOver(i)}var max=ratingsL10n.max;var i;for(i=1;i<=max;i++)setOff(i);for(i=1;i<=current_rating;i++)setOn(i);if(insert_half>rating_score)setHalf(insert_half);if(!isNaN(curval)){if(event.type=="mouseover")for(i=1;i<=Math.min(curval,rating_score);i++)setOver(i);else for(i=1;i<=curval;i++)setOver(i)}if(event.type=="mouseover")for(i=1;i<=rating_score;i++)setOver(i);for(i=1;i<=max;i++)$j("#rating_"+post_id+"_"+i).attr("src",next_images[i]);updateText($j("#ratings_"+post_id+"_text"),post_ratings_el,event.type=="mouseout")}function updateText($text_el,$element,mouseout){if($text_el.length){if(mouseout)$text_el.hide().empty();else $text_el.html($element.data("ratingsText")).show()}}function rate_post_success(post_id,data){$j("#post-ratings-"+post_id).html(data);if(ratingsL10n.show_loading){$j("#post-ratings-"+post_id+"-loading").hide()}if(ratingsL10n.show_fading){$j("#post-ratings-"+post_id).fadeTo("def",1)}}function rate_post(event){var post_ratings_el=$j(event.target);var post_id=$j(event.target).data("id");var post_rating=$j(event.target).data("votes");var captcha_response="";if(!is_using_ajax(post_id)){var value_holder=non_ajax_hidden_parent(post_id);var curval=$j(value_holder).val();$j(value_holder).val(null);$j("#rating_"+post_id+"_"+curval).trigger("mouseout");if(curval!=post_rating){$j("#rating_"+post_id+"_"+post_rating).trigger("mouseover");$j(value_holder).val(post_rating)}return}if(ratingsL10n.captcha_sitekey&&ratingsL10n.captcha_sitekey.length){if(postratings_captcha===null){postratings_captcha=grecaptcha.render("g-recaptcha-response",{sitekey:ratingsL10n.captcha_sitekey});return}else{captcha_response=grecaptcha.getResponse(postratings_captcha);if(!grecaptcha.getResponse(postratings_captcha)){return}else{$j("#g-recaptcha-response").remove()}}}if(!is_being_rated){var post_ratings_nonce=$j(post_ratings_el).parent(".post-ratings").data("nonce");is_being_rated=true;if(ratingsL10n.show_fading){$j(post_ratings_el).fadeTo("def",0,function(){if(ratingsL10n.show_loading){$j("#post-ratings-"+post_id+"-loading").show()}})}else{if(ratingsL10n.show_loading){$j("#post-ratings-"+post_id+"-loading").show()}}$j.post({xhrFields:{withCredentials:true},dataType:"html",url:ratingsL10n.ajax_url,data:"action=postratings&pid="+post_id+"&rate="+post_rating+"&postratings_"+post_id+"_nonce="+post_ratings_nonce+"&g-recaptcha-response="+captcha_response,cache:false}).done(function(data){rate_post_success(post_id,data)}).always(function(){is_being_rated=false})}else{alert(ratingsL10n.text_wait)}} \ No newline at end of file +var ratings_mouseover_image,$j=jQuery.noConflict(),is_being_rated=!1,postratings_captcha=null;function postratings_init_vars(){if(ratingsL10n.custom=parseInt(ratingsL10n.custom),ratingsL10n.max=parseInt(ratingsL10n.max),ratingsL10n.show_loading=parseInt(ratingsL10n.show_loading),ratingsL10n.show_fading=parseInt(ratingsL10n.show_fading),ratingsL10n.baseimg=ratingsL10n.plugin_url+"/images/"+ratingsL10n.image+"/rating",ratingsL10n.rtl=parseInt(ratingsL10n.rtl),ratingsL10n.custom){ratings_mouseover_image=[];for(var t=1;t<=ratingsL10n.max;t++)ratings_mouseover_image[t]=new Image,ratings_mouseover_image[t].src=ratingsL10n.baseimg+"_"+t+"_over."+ratingsL10n.image_ext}else(ratings_mouseover_image=new Image).src=ratingsL10n.baseimg+"_over."+ratingsL10n.image_ext}function postratings_setup_evt_listeners(){jQuery("img[data-votes]").on("mouseover mouseout",current_rating).on("click keypress",rate_post)}function getRtlI(t){return ratingsL10n.rtl?ratingsL10n.max-t+1:t}function getOver(t){return ratingsL10n.custom?ratings_mouseover_image[getRtlI(t)].src:ratings_mouseover_image.src}function getOn(t){return ratingsL10n.baseimg+(ratingsL10n.custom?"_"+getRtlI(t):"")+"_"+getRtlDir("on")+"."+ratingsL10n.image_ext}function getOff(t){return ratingsL10n.baseimg+(ratingsL10n.custom?"_"+getRtlI(t):"")+"_"+getRtlDir("off")+"."+ratingsL10n.image_ext}function getHalf(t){return ratingsL10n.baseimg+(ratingsL10n.custom?"_"+getRtlI(t):"")+"_"+getRtlDir("half")+"."+ratingsL10n.image_ext}function getRtlDir(t){if(!ratingsL10n.rtl)return t;switch(t){case"on":return"off";case"off":return"on";case"half":return"half-rtl";default:return""}}function is_using_ajax(t){return Boolean($j("#post-ratings-"+t).data("ajax"))}function non_ajax_hidden_parent(t){var n=$j('input[name="wp_postrating_form_value_'+t+'"]');return 1==n.length&&n}function current_rating(t){var n=$j(t.target),a=$j(t.target).data("id"),e=$j(t.target).data("currentRating"),r=$j(t.target).data("votes"),i=$j(t.target).data("half");if(!is_being_rated){var s=NaN;if(!is_using_ajax(a)){var g=non_ajax_hidden_parent(a);s=parseInt(g.val())}var o,_=[],u=ratingsL10n.max;for(o=1;o<=u;o++)f(o);for(o=1;o<=e;o++)c(o);if(i>r&&function(t){_[t]=getHalf(t)}(i),!isNaN(s))if("mouseover"==t.type)for(o=1;o<=Math.min(s,r);o++)p(o);else for(o=1;o<=s;o++)p(o);if("mouseover"==t.type)for(o=1;o<=r;o++)p(o);for(o=1;o<=u;o++)document.querySelector("img#rating_"+a+"_"+o).setAttribute("src",_[o]);updateText($j("#ratings_"+a+"_text"),n,"mouseout"==t.type)}function c(t){_[t]=getOn(t)}function f(t){_[t]=getOff(t)}function p(t){_[t]=getOver(t)}}function updateText(t,n,a){t.length&&(a?t.hide().empty():t.html(n.data("ratingsText")).show())}function rate_post_success(t,n){$j("#post-ratings-"+t).html(n),ratingsL10n.show_loading&&$j("#post-ratings-"+t+"-loading").hide(),ratingsL10n.show_fading&&$j("#post-ratings-"+t).fadeTo("def",1)}function rate_post(t){var n=$j(t.target),a=$j(t.target).data("id"),e=$j(t.target).data("votes"),r="";if(!is_using_ajax(a)){var i=non_ajax_hidden_parent(a),s=$j(i).val();return $j(i).val(null),$j("#rating_"+a+"_"+s).trigger("mouseout"),void(s!=e&&($j("#rating_"+a+"_"+e).trigger("mouseover"),$j(i).val(e)))}if(ratingsL10n.captcha_sitekey&&ratingsL10n.captcha_sitekey.length){if(null===postratings_captcha)return void(postratings_captcha=grecaptcha.render("g-recaptcha-response",{sitekey:ratingsL10n.captcha_sitekey}));if(r=grecaptcha.getResponse(postratings_captcha),!grecaptcha.getResponse(postratings_captcha))return;$j("#g-recaptcha-response").remove()}if(is_being_rated)alert(ratingsL10n.text_wait);else{var g=$j(n).parent(".post-ratings").data("nonce");is_being_rated=!0,ratingsL10n.show_fading?$j(n).fadeTo("def",0,function(){ratingsL10n.show_loading&&$j("#post-ratings-"+a+"-loading").show()}):ratingsL10n.show_loading&&$j("#post-ratings-"+a+"-loading").show(),$j.post({xhrFields:{withCredentials:!0},dataType:"html",url:ratingsL10n.ajax_url,data:"action=postratings&pid="+a+"&rate="+e+"&postratings_"+a+"_nonce="+g+"&g-recaptcha-response="+r,cache:!1}).done(function(t){rate_post_success(a,t)}).always(function(){is_being_rated=!1})}}jQuery(function(){postratings_init_vars(),postratings_setup_evt_listeners()});
+ false); // default value if it has never been saved before +?> + + />  +    + + + />  + Configure Google's Recaptcha sitekeys inside 'wpcf7-integration','service'=>'recaptcha','action'=>'setup'], menu_page_url('wpcf7', false))) . "\">contact-form-7 in order to enable wp-postratings recaptcha

"; + } + else if(! $recaptcha_possible) { + echo "

Install Contact Form 7 in order to use Google's Recaptcha with wp-postratings

"; + } + ?> +