Skip to content

Instantly share code, notes, and snippets.

@igorbenic
Last active February 10, 2021 09:17
Show Gist options
  • Select an option

  • Save igorbenic/604209de09e86752ec94390823a083de to your computer and use it in GitHub Desktop.

Select an option

Save igorbenic/604209de09e86752ec94390823a083de to your computer and use it in GitHub Desktop.
How to Create a WordPress Rating Plugin for Your Content | http://www.ibenic.com/wordpress-rating-plugin-content
#contentRating {
position: fixed;
bottom:0;
right: 10px;
overflow: hidden;
text-align: center;
}
#toggleRating {
background:#333;
color: white;
border:none;
box-shadow: none;
text-transform: uppercase;
font-size: small;
position: relative;
}
#toggleRating .arrow {
display: inline-block;
vertical-align: middle;
width: 0px;
height: 0px;
border: 4px solid transparent;
position: absolute;
border-bottom-color: rgba(225,225,225, 0.5);
right: 5px;
top: 15px;
}
#toggleRating.active .arrow {
border-bottom-color: transparent;
border-top-color: rgba(225,225,225, 0.5);
top: 20px;
}
#entryRating {
height:0;
overflow: hidden;
}
.rc-rating-content {
box-sizing: border-box;
background:#333;
color:white;
padding:0 20px;
border-top-left-radius: 3px;
border-top-right-radius: 3px;
}
.rc-rating-content ul {
list-style: none;
padding: 0;
margin: 0;
}
.rc-rating-content ul li {
display: inline-block;
padding:10px;
position: relative;
color: white;
}
.rc-rating-content ul li label {
cursor: pointer;
padding: 5px 10px;
border-radius:3px;
color: white;
}
.rc-rating-content ul li input {
position: absolute;
visibility: hidden;
}
.rc-rating-content ul li input:checked ~ label {
background-color: #fb8b33;
}
#entryRating.active {
height: auto;
padding:20px;
}
#submitRating {
background: white;
color: #333;
font-size: 12px;
text-transform: uppercase;
border-radius:3px;
border:none;
box-shadow: none;
padding: 5px 10px;
}
#ratingErrors {
color:#fb8b33;
font-style: italic;
}
( function( $ ) {
$( document ).ready(function() {
$("#toggleRating").on( 'click', function( e ){
e.preventDefault();
$(this).toggleClass('active');
var $text = $(this).children('.text');
$("#entryRating").toggleClass('active');
if( $("#entryRating").hasClass('active') ) {
$text.html( rc_object.text.close_rating );
} else {
$text.html( rc_object.text.rate_it );
}
});
$("#submitRating").on( 'click', function(){
var $this = $( this ),
$text = $("#toggleRating").children('.text'),
val = $("input[name=ratingValue]:checked").val();
$("#ratingErrors").html('');
if( ! val ) {
$("#ratingErrors").html( rc_object.text.choose_rate );
} else {
var rate_id = $this.attr("data-rate");
if( rate_id == 0 ) {
return;
}
$this.html( rc_object.text.submitting );
$.ajax({
url: rc_object.ajax_url,
type: 'POST',
dataType: 'json',
data: { action: 'submit_rating', _wpnonce: rc_object.nonce, rating: val, post_id: rate_id },
success: function( resp ) {
if( resp.success ) {
$text.html( rc_object.text.thank_you );
$("#entryRating").removeClass( 'active' );
} else {
$("#ratingErrors").html( resp.message );
$this.html( rc_object.text.submit );
}
}
});
}
});
});
})(jQuery);
<?php
/**
* Plugin Name: Rating Content
* Description: Plugin for the tutorial
* Author: Igor Benic
* Author URI: http://www.ibenic.com
* Textdomain: rc
*/
if( ! defined( 'ABSPATH' ) ) {
return;
}
<?php
add_action( 'wp_ajax_submit_rating', 'rc_submit_rating' );
add_action( 'wp_ajax_nopriv_submit_rating', 'rc_submit_rating' );
/**
* Submitting Rating
* @return string JSON encoded array
*/
function rc_submit_rating() {
check_ajax_referer( 'rc_rating', '_wpnonce', true );
$result = array( 'success' => 1, 'message' => '' );
$ratingCookie = isset( $_COOKIE['rc_rating'] ) ? unserialize( base64_decode( $_COOKIE['rc_rating'] ) ) : array();
$rate_id = isset( $_POST['post_id'] ) ? $_POST['post_id'] : 0;
if( ! $ratingCookie ) {
$ratingCookie = array();
}
$ratingCookie = array();
if( $rate_id > 0 ) {
if( ! in_array( $rate_id, $ratingCookie ) ) {
$rate_value = isset( $_POST['rating'] ) ? $_POST['rating'] : 0;
if( $rate_value > 0 ) {
$success = add_post_meta( $rate_id, 'rc_rating', $rate_value );
if( $success ) {
$result['message'] = __( 'Thank you for rating!', 'rc' );
$ratingCookie[] = $rate_id;
$expire = time() + 30*DAY_IN_SECONDS;
setcookie( 'rc_rating', base64_encode(serialize( $ratingCookie )), $expire, COOKIEPATH, COOKIE_DOMAIN );
$_COOKIE['rc_rating'] = base64_encode(serialize( $ratingCookie ));
}
} else {
$result['success'] = 0;
$result['message'] = __( 'Something went wrong. Try to rate later', 'rc' );
}
} else {
$result['success'] = 0;
$result['message'] = __( 'You have already rated this content.', 'rc' );
}
} else {
$result['success'] = 0;
$result['message'] = __( 'Something went wrong. Try to rate later', 'rc' );
}
echo json_encode( $result );
wp_die();
}
<?php
/**
* Top Level Menu and submenu
*/
function rc_rating_options_page()
{
// add top level menu page
add_menu_page(
__( 'Ratings', 'rc' ),
__( 'Ratings', 'rc' ),
'manage_options',
'rc_rating',
'rc_rating_page_html',
'dashicons-star-empty'
);
add_submenu_page(
'rc_rating',
__( 'Settings', 'rc' ),
__( 'Settings', 'rc' ),
'manage_options',
'rc_rating_settings',
'rc_rating_settings_html'
);
}
add_action('admin_menu', 'rc_rating_options_page');
<?php
/**
* The page to display all rated content
* @return void
*/
function rc_rating_page_html() {
// check user capabilities
if (!current_user_can('manage_options')) {
return;
}
global $wpdb;
// SQL query to get all the content which has the meta key 'rc_rating'. Group the content by the ID and get an average rating on each
$sql = "SELECT * FROM ( SELECT p.post_title 'title', p.guid 'link', post_id, AVG(meta_value) AS rating, count(meta_value) 'count' FROM {$wpdb->prefix}postmeta pm";
$sql .= " LEFT JOIN wp_posts p ON p.ID = pm.post_id";
$sql .= " where meta_key = 'rc_rating' group by post_id ) as ratingTable ORDER BY rating DESC";
$result = $wpdb->get_results( $sql, 'ARRAY_A' );
?>
<div class="wrap">
<h1><?php echo esc_html(get_admin_page_title()); ?></h1>
<div id="poststuff">
<table class="form-table widefat">
<thead>
<tr>
<td>
<strong><?php _e( 'Content', 'rc' ); ?></strong>
</td>
<td>
<strong><?php _e( 'Rating', 'rc' ); ?></strong>
</td>
<td>
<strong><?php _e( 'No. of Ratings', 'rc' ); ?></strong>
</td>
</tr>
</thead>
<tbody>
<?php
foreach ( $result as $row ) {
echo '<tr>';
echo '<td>' . $row['title'] . '<br/><a href="' . $row['link'] . '" target="_blank">' . __( 'View the Content', 'rc' ) . '</a></td>';
echo '<td>' . round( $row['rating'], 2 ) . '</td>';
echo '<td>' . $row['count'] . '</td>';
echo '</tr>';
}
?>
</tbody>
</table>
</div>
</div>
<?php
}
<?php
/**
* Registering Settings for Rating Settings
*/
function rc_ratings_settings_init()
{
// Registering the setting 'rc_rating_types' for the page 'rc_rating_settings'
register_setting( 'rc_rating_settings', 'rc_rating_types');
// Registering the section 'rc_rating_section' for the page 'rc_rating_settings'
add_settings_section(
'rc_rating_section',
'',
'',
'rc_rating_settings'
);
// Registering the field for the setting 'rc_rating_types' on the page 'rc_rating_settings' under section 'rc_rating_section'
add_settings_field(
'rc_rating_types', // as of WP 4.6 this value is used only internally
// use $args' label_for to populate the id inside the callback
__('Show Rating on Content:', 'wporg'),
'rc_rating_types_html',
'rc_rating_settings',
'rc_rating_section',
[
'label_for' => 'rc_rating_pages',
'class' => 'wporg_row',
'wporg_custom_data' => 'custom',
]
);
}
add_action('admin_init', 'rc_ratings_settings_init');
<?php
/**
* Get all Custom Post Types that are available publicly
* For each of those add a checkbox to choose
* @param array $args
* @return void
*/
function rc_rating_types_html( $args ) {
$post_types = get_post_types( array( 'public' => true ), 'objects' );
// get the value of the setting we've registered with register_setting()
$rating_types = get_option('rc_rating_types', array());
if( ! empty( $post_types ) ) {
foreach ( $post_types as $key => $value ) {
$isChecked = in_array( $key, $rating_types );
echo '<input ' . ( $isChecked ? 'checked="checked"' : '' ) . ' type="checkbox" name="rc_rating_types[]" value="' . $key . '" /> ' . $value->label . '<br/>';
}
}
}
<?php
/**
* Displaying the form with our Rating settings
* @return void
*/
function rc_rating_settings_html() {
// check user capabilities
if (!current_user_can('manage_options')) {
return;
}
?>
<div class="wrap">
<h1><?php echo esc_html(get_admin_page_title()); ?></h1>
<form action="options.php" method="post">
<?php
// output security fields for the registered setting "rc_rating_settings"
settings_fields('rc_rating_settings');
// output setting sections and their fields
do_settings_sections('rc_rating_settings');
// output save settings button
submit_button('Save Settings');
?>
</form>
</div>
<?php
}
<?php
/**
* Enqueueing Scripts
* @return void
*/
function rc_rating_scripts() {
wp_enqueue_style( 'rating-css', plugin_dir_url( __FILE__ ) . 'rating.css', array(), '', 'screen' );
wp_register_script( 'rating-js', plugin_dir_url( __FILE__ ) . 'rating.js', array('jquery'), '', true );
wp_localize_script( 'rating-js', 'rc_object', array(
'ajax_url' => admin_url( 'admin-ajax.php' ),
'nonce' => wp_create_nonce( 'rc_rating' ),
'text' => array(
'close_rating' => __( 'Close Rating', 'rc' ),
'rate_it' => __( 'Rate It', 'rc' ),
'choose_rate' => __( 'Choose a Rate', 'rc' ),
'submitting' => __( 'Submitting...', 'rc' ),
'thank_you' => __( 'Thank You for Your Rating!', 'rc' ),
'submit' => __( 'Submit', 'rc' ),
)
));
wp_enqueue_script( 'rating-js' );
}
<?php
/**
* Checking for Rating
* @return void
*/
function rc_check_for_rating() {
$rating_types = get_option( 'rc_rating_types', array() );
if( is_array( $rating_types ) && count( $rating_types ) > 0 && is_singular( $rating_types ) ) {
$rate_id = get_the_id();
$ratingCookie = isset( $_COOKIE['rc_rating'] ) ? unserialize( base64_decode( $_COOKIE['rc_rating'] ) ) : array();
if( ! in_array( $rate_id, $ratingCookie ) ) {
// This content has not been rated yet by that user
add_action( 'wp_enqueue_scripts', 'rc_rating_scripts');
add_action( 'wp_footer', 'rc_rating_render' );
}
}
}
add_action( 'template_redirect', 'rc_check_for_rating' );
<?php
/**
* Render Rating
* @return void
*/
function rc_rating_render() {
$ratingValues = 5;
?>
<div id="contentRating" class="rc-rating">
<button type="button" id="toggleRating" class="active">
<span class="text">
<?php _e( 'Rate It', 'rc' ); ?>
</span>
<span class="arrow"></span>
</button>
<div id="entryRating" class="rc-rating-content active">
<div class="errors" id="ratingErrors"></div>
<ul>
<?php for( $i = 1; $i <= $ratingValues; $i++ ) {
echo '<li>';
echo '<input type="radio" name="ratingValue" value="' . $i . '" id="rating' . $i . '"/>';;
echo '<label for="rating' . $i . '">';
echo $i;
echo '</label>';
echo '</li>';
}
?>
</ul>
<button type="button" data-rate="<?php echo get_the_id(); ?>"id="submitRating"><?php _e( 'Submit', 'rc' ); ?></button>
</div>
</div>
<?php
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment