prefix . 'star_ratings'; $charset_collate = $wpdb->get_charset_collate(); $sql = "CREATE TABLE $table_name ( id mediumint(9) NOT NULL AUTO_INCREMENT, post_id bigint(20) NOT NULL, rating tinyint(1) NOT NULL, rated tinyint(1) NOT NULL DEFAULT 0, ip_address varchar(45) NOT NULL, PRIMARY KEY (id) ) $charset_collate;"; require_once(ABSPATH . 'wp-admin/includes/upgrade.php'); dbDelta($sql); } // Set default settings function strpgn_set_default_settings() { $defaults = array( 'strpgn_apply_to' => 'posts', 'strpgn_star_color_empty' => '#9d9d9d', 'strpgn_star_color_filled' => '#26f553', 'strpgn_star_color_hover' => '#ffed25', 'strpgn_star_size' => 43, 'strpgn_average_font_size' => 70, 'strpgn_details_font_size' => 16, 'strpgn_container_alignment' => 'center', // Average rating margins 'strpgn_average_margin_top' => 0, 'strpgn_average_margin_right' => 15, 'strpgn_average_margin_bottom' => 0, 'strpgn_average_margin_left' => 0, // Stars margins 'strpgn_stars_margin_top' => 0, 'strpgn_stars_margin_right' => 0, 'strpgn_stars_margin_bottom' => -5, 'strpgn_stars_margin_left' => 0, // Total ratings margins 'strpgn_total_margin_top' => -5, 'strpgn_total_margin_right' => 0, 'strpgn_total_margin_bottom' => 5, 'strpgn_total_margin_left' => 0 ); foreach ($defaults as $key => $value) { if (get_option($key) === false) { update_option($key, $value); } } } register_activation_hook(__FILE__, 'strpgn_create_table'); register_activation_hook(__FILE__, 'strpgn_set_default_settings'); // Function to check if shortcode exists in the content function strpgn_has_rating_shortcode() { global $post; if (is_a($post, 'WP_Post') && has_shortcode($post->post_content, 'strpgn_rating')) { return true; } return false; } // Enqueue scripts and styles function strpgn_enqueue_scripts() { // Get the apply-to setting $apply_to = get_option('strpgn_apply_to'); // Check if current post type matches the setting, or if we're using a shortcode if ( ($apply_to === 'posts' && is_single()) || ($apply_to === 'pages' && is_page()) || ($apply_to === 'both' && (is_single() || is_page())) || strpgn_has_rating_shortcode() ) { wp_enqueue_script('jquery'); // Define the version for scripts and styles $version = '1.9.9'; // Updated to match plugin version // Enqueue confetti library with its version to avoid caching issues wp_enqueue_script( 'strpgn-confetti', plugins_url('/js/confetti.browser.min.js', __FILE__), array('jquery'), '1.4.0', true ); // Enqueue the rating script and style with versioning wp_enqueue_style('strpgn-rating-style', plugins_url('/css/style.css', __FILE__), array(), $version); wp_enqueue_script('strpgn-rating-script', plugins_url('/js/rating.js', __FILE__), array('jquery'), $version, true); // Localize the script for AJAX and settings $ajax_nonce = wp_create_nonce('strpgn_rating_nonce'); wp_localize_script('strpgn-rating-script', 'strpgn_ajax_object', array( 'ajax_url' => admin_url('admin-ajax.php'), 'nonce' => $ajax_nonce, 'star_color_empty' => get_option('strpgn_star_color_empty', '#9d9d9d'), 'star_color_filled' => get_option('strpgn_star_color_filled', '#26f553'), 'star_color_hover' => get_option('strpgn_star_color_hover', '#ffed25') )); // Add inline CSS with custom settings $custom_css = " .strpgn-rating-container { text-align: " . esc_attr(get_option('strpgn_container_alignment', 'center')) . "; } .strpgn-star { color: " . esc_attr(get_option('strpgn_star_color_empty', '#9d9d9d')) . "; font-size: " . esc_attr(get_option('strpgn_star_size', 25)) . "px; } .strpgn-star-filled { color: " . esc_attr(get_option('strpgn_star_color_filled', '#26f553')) . "; } .strpgn-star:hover { color: " . esc_attr(get_option('strpgn_star_color_hover', '#ffed25')) . "; } .strpgn-average-rating { font-size: " . esc_attr(get_option('strpgn_average_font_size', 47)) . "px; margin-top: " . esc_attr(get_option('strpgn_average_margin_top', 0)) . "px; margin-right: " . esc_attr(get_option('strpgn_average_margin_right', 20)) . "px; margin-bottom: " . esc_attr(get_option('strpgn_average_margin_bottom', 0)) . "px; margin-left: " . esc_attr(get_option('strpgn_average_margin_left', 0)) . "px; } .strpgn-stars { margin-top: " . esc_attr(get_option('strpgn_stars_margin_top', 0)) . "px; margin-right: " . esc_attr(get_option('strpgn_stars_margin_right', 0)) . "px; margin-bottom: " . esc_attr(get_option('strpgn_stars_margin_bottom', 5)) . "px; margin-left: " . esc_attr(get_option('strpgn_stars_margin_left', 0)) . "px; } .strpgn-total-ratings { font-size: " . esc_attr(get_option('strpgn_details_font_size', 16)) . "px; margin-top: " . esc_attr(get_option('strpgn_total_margin_top', 4)) . "px; margin-right: " . esc_attr(get_option('strpgn_total_margin_right', 0)) . "px; margin-bottom: " . esc_attr(get_option('strpgn_total_margin_bottom', 0)) . "px; margin-left: " . esc_attr(get_option('strpgn_total_margin_left', 0)) . "px; } "; wp_add_inline_style('strpgn-rating-style', $custom_css); } // Admin scripts and styles if (is_admin()) { wp_enqueue_style('wp-color-picker'); wp_enqueue_script('wp-color-picker'); } } add_action('wp_enqueue_scripts', 'strpgn_enqueue_scripts'); // Add star rating to the content (for user interaction) function strpgn_add_star_rating($content) { // Get current post ID $post_id = get_the_ID(); // Check post meta for hide_auto flag - this is more reliable than global variable if ($post_id && get_post_meta($post_id, 'strpgn_hide_auto_display', true) === 'yes') { return $content; // Skip automatic display } // Also check global flag as a fallback global $strpgn_hide_auto_display; if (isset($strpgn_hide_auto_display) && $strpgn_hide_auto_display === true) { return $content; // Skip automatic display } if (is_single() || is_page()) { // Get the apply-to setting $apply_to = get_option('strpgn_apply_to'); // Check if current post type matches the setting if (($apply_to === 'posts' && is_single()) || ($apply_to === 'pages' && is_page()) || $apply_to === 'both') { global $wpdb; $post_id = get_the_ID(); // Cache the rating count $rating_count = wp_cache_get('strpgn_rating_count_' . $post_id); if ($rating_count === false) { $rating_count = $wpdb->get_var($wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->prefix}star_ratings WHERE post_id = %d AND rated = 1", $post_id )); wp_cache_set('strpgn_rating_count_' . $post_id, $rating_count, '', 12 * HOUR_IN_SECONDS); } if ($rating_count == 0) { $content .= '
'; } } } return $content; } add_filter('the_content', 'strpgn_add_star_rating'); // Display average rating and schema markup (only if there are ratings) function strpgn_display_average_rating($content) { // Get current post ID $post_id = get_the_ID(); // Check post meta for hide_auto flag - this is more reliable than global variable if ($post_id && get_post_meta($post_id, 'strpgn_hide_auto_display', true) === 'yes') { return $content; // Skip automatic display } // Also check global flag as a fallback global $strpgn_hide_auto_display; if (isset($strpgn_hide_auto_display) && $strpgn_hide_auto_display === true) { return $content; // Skip automatic display } if (is_single() || is_page()) { // Get the apply-to setting $apply_to = get_option('strpgn_apply_to'); // Check if current post type matches the setting if (($apply_to === 'posts' && is_single()) || ($apply_to === 'pages' && is_page()) || $apply_to === 'both') { global $wpdb; $post_id = get_the_ID(); $cache_key = 'strpgn_average_rating_' . $post_id; $cached_data = wp_cache_get($cache_key); if ($cached_data === false) { $average_rating = round($wpdb->get_var($wpdb->prepare( "SELECT AVG(rating) FROM {$wpdb->prefix}star_ratings WHERE post_id = %d AND rated = 1", $post_id )), 1); $rating_count = $wpdb->get_var($wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->prefix}star_ratings WHERE post_id = %d AND rated = 1", $post_id )); wp_cache_set($cache_key, array('average' => $average_rating, 'count' => $rating_count), '', 12 * HOUR_IN_SECONDS); } else { $average_rating = $cached_data['average']; $rating_count = $cached_data['count']; } if ($average_rating !== null && $rating_count !== null) { $output = ''; $schema = ''; $content .= $schema . $output; } } } return $content; } add_filter('the_content', 'strpgn_display_average_rating'); // Save star rating function strpgn_save_star_rating() { global $wpdb; check_ajax_referer('strpgn_rating_nonce', 'nonce'); // Updated nonce name $post_id = isset($_POST['post_id']) ? intval($_POST['post_id']) : 0; $rating = isset($_POST['rating']) ? intval($_POST['rating']) : 0; // Validate and sanitize IP address $ip_address = ''; if ( isset($_SERVER['REMOTE_ADDR']) ) { $ip_address = sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ) ); } if ($post_id <= 0 || $rating <= 0 || $rating > 5) { wp_send_json_error('Invalid rating or post ID'); return; } // Implement caching for existing rating check $cache_key = 'strpgn_existing_rating_' . $post_id . '_' . md5($ip_address); $existing_rating = wp_cache_get($cache_key); if ($existing_rating === false) { $existing_rating = $wpdb->get_var($wpdb->prepare( "SELECT id FROM {$wpdb->prefix}star_ratings WHERE post_id = %d AND ip_address = %s", $post_id, $ip_address )); wp_cache_set($cache_key, $existing_rating, '', 12 * HOUR_IN_SECONDS); } if ($existing_rating) { wp_send_json_error('You have already rated this post π'); return; } $result = $wpdb->insert( $wpdb->prefix . 'star_ratings', array( 'post_id' => $post_id, 'rating' => $rating, 'rated' => 1, 'ip_address' => $ip_address ), array('%d', '%d', '%d', '%s') ); if ($result) { // Clear the cache for this postβs rating after submission to ensure fresh data is loaded wp_cache_delete('strpgn_average_rating_' . $post_id); wp_send_json_success(); } else { wp_send_json_error('Database insertion failed'); } } add_action('wp_ajax_save_star_rating', 'strpgn_save_star_rating'); add_action('wp_ajax_nopriv_save_star_rating', 'strpgn_save_star_rating'); // Get average rating function strpgn_get_average_rating() { global $wpdb; // Verify nonce check_ajax_referer('strpgn_rating_nonce', 'nonce'); // Updated nonce name if (!isset($_POST['post_id'])) { wp_send_json_error('Invalid data'); return; } $post_id = intval($_POST['post_id']); $cache_key = 'strpgn_average_rating_' . $post_id; $cached_data = wp_cache_get($cache_key); if ($cached_data === false) { $average_rating = round($wpdb->get_var($wpdb->prepare( "SELECT AVG(rating) FROM {$wpdb->prefix}star_ratings WHERE post_id = %d AND rated = 1", $post_id )), 1); $rating_count = $wpdb->get_var($wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->prefix}star_ratings WHERE post_id = %d AND rated = 1", $post_id )); // Cache the rating count and average wp_cache_set($cache_key, array('average' => $average_rating, 'count' => $rating_count), '', 12 * HOUR_IN_SECONDS); } else { $average_rating = $cached_data['average']; $rating_count = $cached_data['count']; } wp_send_json_success(array('average_rating' => $average_rating, 'rating_count' => $rating_count)); } add_action('wp_ajax_get_average_rating', 'strpgn_get_average_rating'); add_action('wp_ajax_nopriv_get_average_rating', 'strpgn_get_average_rating'); // Add custom links (Support and Donate) to the plugin on the plugins page function strpgn_plugin_links($links, $file) { if (strpos($file, 'aggregate-rating-schema-generator-for-blogs.php') !== false) { $new_links = array( '' . __('Support') . '', '' . __('Buy a Coffee') . '' ); $links = array_merge($links, $new_links); } return $links; } add_filter('plugin_row_meta', 'strpgn_plugin_links', 10, 2); // Shortcode for displaying ratings function strpgn_rating_shortcode($atts) { // Extract attributes $atts = shortcode_atts( array( 'post_id' => 0, 'hide_auto' => false, // New parameter to hide automatic display ), $atts, 'strpgn_rating' ); // If hide_auto is true, store it in post meta to ensure it persists if ($atts['hide_auto'] === 'true' || $atts['hide_auto'] === '1' || $atts['hide_auto'] === true) { // Get the post ID $post_id = (int) $atts['post_id']; if ($post_id === 0) { $post_id = get_the_ID(); } // Set post meta flag and global flag if ($post_id) { update_post_meta($post_id, 'strpgn_hide_auto_display', 'yes'); global $strpgn_hide_auto_display; $strpgn_hide_auto_display = true; } } // If no post_id is specified, use the current post $post_id = (int) $atts['post_id']; if ($post_id === 0) { $post_id = get_the_ID(); } // If no valid post ID, return empty if (!$post_id) { return ''; } global $wpdb; $output = ''; // Get the ratings data $cache_key = 'strpgn_average_rating_' . $post_id; $cached_data = wp_cache_get($cache_key); if ($cached_data === false) { $average_rating = round($wpdb->get_var($wpdb->prepare( "SELECT AVG(rating) FROM {$wpdb->prefix}star_ratings WHERE post_id = %d AND rated = 1", $post_id )), 1); $rating_count = $wpdb->get_var($wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->prefix}star_ratings WHERE post_id = %d AND rated = 1", $post_id )); wp_cache_set($cache_key, array('average' => $average_rating, 'count' => $rating_count), '', 12 * HOUR_IN_SECONDS); } else { $average_rating = $cached_data['average']; $rating_count = $cached_data['count']; } // Check if we have ratings if ($rating_count > 0) { // Display average rating $output .= ''; // Include schema.org markup $output .= ''; } else { // Display rating form $output .= ''; } return $output; } add_shortcode('strpgn_rating', 'strpgn_rating_shortcode');