Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ft/rate star #1

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions assets/js/ramphor-rating.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
function ramphor_start_update_rate() {
}
function ramphor_end_update_rate() {
}

function ramphor_set_star_rating(rating, done = ramphor_end_update_rate) {
// var testimonial_rating; This is global variable
ramphor_rating_global = window.ramphor_rating_global || {};
if (!ramphor_rating_global.set_rate_url || !ramphor_rating_global.post_id) {
return;
}
ramphor_start_update_rate();
tmpRating = ramphor_popcorn_rating.getRating();
ramphor_popcorn_rating.setRating(rating);

var xhr = new XMLHttpRequest();

xhr.onload = function() {
if (xhr.status >= 200 && xhr.status < 300) {
response = JSON.parse(xhr.response);
if (!response.success) {
ramphor_popcorn_rating.setRating(tmpRating);
}
} else {
ramphor_popcorn_rating.setRating(tmpRating);
}
if (typeof done === 'function') {
done();
}
}

xhr.open('POST', ramphor_rating_global.set_rate_url);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(JSON.stringify({
rating: rating,
post_id: ramphor_rating_global.post_id,
nonce: ramphor_rating_global.current_nonce,
}));
}
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@
"Ramphor\\Popcorn\\": "includes/Popcorn/"
},
"files": [
"./includes/Ramphor_Popcorn.php"
"./includes/Ramphor_Popcorn.php",
"./includes/functions.php"
]
}
}
2 changes: 2 additions & 0 deletions includes/Popcorn/Admin/Admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@
use Ramphor\Popcorn\Admin\Metabox\EditVideoInfo;
use Ramphor\PostColumns\Columns\ThumbnailColumn;
use Ramphor\PostColumns\ColumnsManager;

use Ramphor_Popcorn;

class Admin
{
protected $editVideoInfoMetabox;
protected $ratingVideoMetabox;

public function __construct()
{
Expand Down
23 changes: 23 additions & 0 deletions includes/Popcorn/Installer.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,31 @@ protected static function createVideoTable()
return $wpdb->query($sql);
}

protected static function createRatingTable()
{
/**
* [$wpdb description]
*
* @var \wpdb
*/
global $wpdb;
$sql = "CREATE TABLE IF NOT EXISTS `{$wpdb->prefix}popcorn_ratings` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`post_id` BIGINT NOT NULL,
`stars` FLOAT NOT NULL DEFAULT 0,
`user_id` BIGINT NOT NULL DEFAULT 0,
`comment` TEXT,
`user_ip` TEXT NOT NULL,
`created_at` DATETIME DEFAULT NOW(),
PRIMARY KEY (`id`)
)";

return $wpdb->query($sql);
}

public static function active()
{
static::createVideoTable();
static::createRatingTable();
}
}
74 changes: 74 additions & 0 deletions includes/Popcorn/Rating/AjaxRequest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?php

namespace Ramphor\Popcorn\Rating;

class AjaxRequest
{
public function init()
{
add_action('wp_ajax_ramphor_set_rate', array($this, 'setRating'));
add_action('wp_ajax_nopriv_ramphor_set_rate', array($this, 'setRating'));
}

public function setRating()
{
$requestPayload = json_decode(file_get_contents('php://input'), true);
if (empty($requestPayload)) {
wp_send_json_error(__('The argument is invalid', 'ramphor_testimonials'));
}
if (empty($requestPayload['post_id']) || is_null(get_post($requestPayload['post_id']))) {
wp_send_json_error(__('The post ID is invalid', 'ramphor_testimonials'));
}
if (
empty($requestPayload['nonce']) ||
!wp_verify_nonce($requestPayload['nonce'], sprintf('set_star_rating_for_%s', $requestPayload['post_id']))
) {
wp_send_json_error(__('The request is not accept by security rules', 'ramphor_testimonials'));
}
// Don't do anything when the rating value is empty
if (empty($requestPayload['rating'])) {
wp_send_json_success();
}

global $wpdb;
$user_id = empty(get_current_user_id()) ? 0 : get_current_user_id();
$user_ip = $this->get_real_ip_address();

$data = array('post_id' => "{$requestPayload['post_id']}", 'stars' => "{$requestPayload['rating']}", 'user_id' => "{$user_id}", 'comment' => '111', 'user_ip' => "{$user_ip}");

if (0 == $user_id) {
$results = $wpdb->get_row("SELECT * FROM {$wpdb->prefix}popcorn_ratings WHERE user_ip = '{$user_ip}' AND NOW() < DATE_ADD(created_at, INTERVAL 1 DAY) ORDER BY created_at DESC LIMIT 1");
if (0 == count((array)$results)) {
$wpdb->insert("{$wpdb->prefix}popcorn_ratings", $data);
}
} else {
$results = $wpdb->get_row("SELECT * FROM {$wpdb->prefix}popcorn_ratings WHERE user_id = '{$user_id}' LIMIT 1");
if (0 == count((array)$results)) {
$wpdb->insert("{$wpdb->prefix}popcorn_ratings", $data);
} else {
$wpdb->update("{$wpdb->prefix}popcorn_ratings", $data, array('id' => $results->id));
}
}
wp_send_json_success($requestPayload['rating']);
}

private function get_real_ip_address()
{
$ip_headers = array(
'HTTP_CF_IPCOUNTRY',
'HTTP_CLIENT_IP',
'HTTP_X_FORWARDED_FOR',
'HTTP_X_FORWARDED',
'HTTP_FORWARDED_FOR',
'HTTP_FORWARDED',
'REMOTE_ADDR'
);

foreach ($ip_headers as $ip_header) {
if (!empty($_SERVER[$ip_header])) {
return $_SERVER[$ip_header];
}
}
return '127.0.0.1';
}
}
152 changes: 152 additions & 0 deletions includes/Popcorn/Rating/Rating.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
<?php

namespace Ramphor\Popcorn\Rating;

use Embrati\Embrati;

use Ramphor_Popcorn;

class Rating
{
protected static $instance;
protected $embrati;
protected $options;
protected $ajax;

private function __construct()
{
$this->initFeatures();
$this->options = $this->defaultOptions();
}

public static function getInstance()
{
if (is_null(self::$instance)) {
self::$instance = new self();
}

return self::$instance;
}

private function assetUrl($path = '')
{
$abspath = constant('ABSPATH');
$embratiAbspath = dirname(__DIR__, 3);
if (PHP_OS === 'WINNT') {
$abspath = str_replace('\\', '/', $abspath);
$embratiAbspath = str_replace('\\', '/', $embratiAbspath);
}
$assetUrl = str_replace($abspath, site_url('/'), $embratiAbspath);

return sprintf(
'%s/assets/%s',
$assetUrl,
$path
);
}

protected function initFeatures()
{
$this->embrati = Embrati::getInstance();
if (is_admin()) {
$this->embrati->registerAdminScripts();
} else {
$this->embrati->registerScripts();
}
$this->embrati->setJsRateCallback('ramphor_set_star_rating');
add_action('wp_enqueue_scripts', array($this->embrati, 'registerStyles'));
}

public function registerScripts()
{
add_action('wp_enqueue_scripts', array($this, '_registerScripts'));
}

public function _registerScripts()
{
wp_register_script('ramphor-ratings', $this->assetUrl('js/ramphor-rating.js'), null, '1.0.0', true);
wp_enqueue_script('ramphor-ratings');

$globalData = array(
'set_rate_url' => admin_url('admin-ajax.php?action=ramphor_set_rate'),
);

if (is_admin()) {
$current_screen = get_current_screen();
if ($current_screen->id === Ramphor_Popcorn::POST_TYPE) {
global $post;
}
} else if (is_singular(Ramphor_Popcorn::POST_TYPE)) {
global $post;
}

$globalData['current_nonce'] = wp_create_nonce('set_star_rating_for_' . $post->ID);
$globalData['post_id'] = $post->ID;

wp_localize_script('ramphor-ratings', 'ramphor_rating_global', $globalData);
}

public function defaultOptions()
{
return array(
'max' => 5,
'step' => 0.5,
'starSize' => 20,
'rating' => 0
);
}

public function addOption($optionName, $optionValue)
{
$this->options[$optionName] = $optionValue;
}

public function setOptions($options)
{
// Parse post layout with default options
$options = apply_filters("ramphor_popcorn-rating-options", $options);
foreach ($options as $optionName => $optionValue) {
$this->addOption($optionName, $optionValue);
}
}

public function getOptions($key = null)
{
if (is_null($key)) {
return (array)$this->options;
}
return isset($this->options[$key]) ? $this->options[$key] : null;
}

public function render($echo = true)
{
if (!$echo) {
ob_start();
}
echo '<div class="ramphor_popcorn-loading"></div>'; // wpcs: XSS Ok

$this->embrati->create('ramphor_popcorn_rating', $this->options);

if (!$echo) {
return ob_get_clean();
}
}

public function meta($post_id, $meta_key = '')
{
$data['max'] = 5;
if (isset($this->options['max'])) $data['max'] = $this->options['max'];
global $wpdb;
$result = $wpdb->get_row("SELECT *, SUM(stars) as sum_star, AVG(stars) as avg_star, count(id) as count_id FROM {$wpdb->prefix}popcorn_ratings WHERE post_id = '{$post_id}' GROUP BY post_id");

if (!is_null($result)) {
foreach ($result as $key => $value) {
$data[$key] = $value;
if ('avg_star' === $key) $data[$key] = floatval($value);
if ($key === $meta_key) break;
}
}
if ($meta_key) return isset($data[$meta_key]) ? $data[$meta_key] : NULL;
return $data;
}
}
1 change: 1 addition & 0 deletions includes/Ramphor_Popcorn.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
class Ramphor_Popcorn
{
const POST_TYPE = 'video';
const POST_META_STAR_RATING = '_ramphor_rating';

protected static $instance;

Expand Down
47 changes: 47 additions & 0 deletions includes/functions.php
Original file line number Diff line number Diff line change
@@ -1 +1,48 @@
<?php

use Ramphor\Popcorn\Rating\Rating;

function show_rating($post = '', $options = [])
{
if (empty($post)) global $post;
if (class_exists(Rating::class)) {
$rating = Rating::getInstance();

$_options = $rating->defaultOptions();
$_options['readOnly'] = true;

$avg_star = $rating->meta($post->ID, 'avg_star');

if (!is_null($avg_star)) $_options['rating'] = $avg_star;

$options = $options + $_options;

$rating->setOptions($options);

return $rating->render(false);
}
return null;
}

function register_rating_js()
{
if (class_exists(Rating::class)) {
$rating = Rating::getInstance();
$rating->registerScripts();
}
}

function register_rating_ajax()
{
$ajax = new \Ramphor\Popcorn\Rating\AjaxRequest();
add_action('init', array($ajax, 'init'));
}

function get_rating_meta($post_id, $meta_key = '')
{
if (class_exists(Rating::class)) {
$rating = Rating::getInstance();
return $rating->meta($post_id, $meta_key);
}
return null;
}