آموزش ساخت سیستم رتبه دهی ستاره ای در js و php

آموزش ساخت سیستم رتبه دهی ستاره ای در js و php

رتبه دهی ستاره ای در js و php – خیلی از مطالب و محصولات اینترنتی دارای بخشی هستند که می توان به محصول و مطلب رتبه دهید تا دیگر کاربران از میزان کیفیت آن مطلب مطلع شوند .

در این آموزش از html , css , js , php , mysql استفاده می کنیم .

فایل index.php

<!DOCTYPE html>
<html lang="fa">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>RapidCode.IR - ساخت جستجوی پیشرفته AJAX با PHP و Javascript</title>
    <link rel="stylesheet" href="static/css/style.css">
</head>

<body>
    <a id="introduce" target="_blank" href="https://rapidcode.ir">رپید کد - کتابخانه مجازی برنامه نویسان</a>

    <div class="container">

<?php 

require_once "posts.php";

$posts = get_posts();

?>


<?php

foreach ($posts as $row):

?>
    <article id="post-<?php echo $row['id'] ?>">
        <img src="<?php echo $row['thumbnail'] ?>" alt="<?php echo $row['title'] ?>">

        <h2><?php echo $row['title'] ?></h2>

        <p><?php echo $row['content'] ?></p>
		
        <?php 
        $stars = $row['rstar'];
        $reviewer_number = $row['rstar_user'];
        $score = $stars == 0 && $reviewer_number == 0 ? 0 : $stars / $reviewer_number;
        $integer_score = ceil($score);
        
        ?>
        <div class="stars-wrapper">
            <?php if($stars != 0 && $reviewer_number != 0): ?>
            <span id="stars-number"><i id="rate"><?php echo round($score , 1) ?></i> از <i id="avg-count"><?php echo $reviewer_number ?></i> رای</span>
            <?php endif; ?>
            <span class="stars-shape" id="post_star_<?php echo $row['id'] ?>" data-post-id="<?php echo $row['id'] ?>">
            <?php 
            for($i=1;$i<=5;$i++):
                
                $offset_svg = 0;
                if($integer_score == 1){
                    $offset_svg = $score;
                }else if(1 < $integer_score){
                    $offset_svg = 1;
                }

                $integer_score--;
                $score--;

                $offset_svg = round($offset_svg , 1);
                $offset_svg *= 100;
                
            ?>
            <svg fill="url(#filler-<?php echo "pid-{$row['id']}-{$i}" ?>)" id="star<?php echo $i ?>" data-item-number="<?php echo $i ?>" class="star" height="511pt" viewBox="0 -10 511.98685 511" width="511pt" xmlns="http://www.w3.org/2000/svg"><defs><linearGradient id="filler-<?php echo "pid-{$row['id']}-{$i}" ?>"><stop id="half-stp-1" offset="<?php echo $offset_svg ?>%"/><stop offset="0"/></linearGradient></defs><path d="m510.652344 185.902344c-3.351563-10.367188-12.546875-17.730469-23.425782-18.710938l-147.773437-13.417968-58.433594-136.769532c-4.308593-10.023437-14.121093-16.511718-25.023437-16.511718s-20.714844 6.488281-25.023438 16.535156l-58.433594 136.746094-147.796874 13.417968c-10.859376 1.003906-20.03125 8.34375-23.402344 18.710938-3.371094 10.367187-.257813 21.738281 7.957031 28.90625l111.699219 97.960937-32.9375 145.089844c-2.410156 10.667969 1.730468 21.695313 10.582031 28.09375 4.757813 3.4375 10.324219 5.1875 15.9375 5.1875 4.839844 0 9.640625-1.304687 13.949219-3.882813l127.46875-76.183593 127.421875 76.183593c9.324219 5.609376 21.078125 5.097657 29.910156-1.304687 8.855469-6.417969 12.992187-17.449219 10.582031-28.09375l-32.9375-145.089844 111.699219-97.941406c8.214844-7.1875 11.351563-18.539063 7.980469-28.925781zm0 0"/></svg>
            <?php endfor; ?>
            </span>
        </div><br>


        <a href="<?php echo $row['link'] ?>" target="_blank">ادامه مطلب</a>

    </article>
<?php endforeach;?>
    </div>

    <script src="static/js/app.js"></script>
</body>
</html>


فایل posts.php برای دسترسی به توابع مورد نیاز جهت تعامل با mysql

فایل posts.php

<?php

$table = "articles";
$mysqli = new mysqli("localhost", "root", "", "posts");
$mysqli->set_charset("utf8");
$stmt = $mysqli->stmt_init();

function get_posts($id = false)
{
	global $table;
	global $mysqli;
	global $stmt;

	$where_statment = "";
	$rows = [];

	if (!empty($id)) {
		if (is_row_exits($id)) {
			$where_statment = "WHERE id=?";
		} else
			return $rows;
	}

	$query = "SELECT * FROM `{$table}` {$where_statment} ORDER BY id DESC";

	$stmt->prepare($query);

	if (!empty($where_statment)) {
		$stmt->bind_param("i", $id);
	}

	if ($stmt->execute() && $res = $stmt->get_result()) {
		if ($stmt->affected_rows || $res->num_rows) {
			while ($row_loop = $res->fetch_assoc()) {
				$rows[] = $row_loop;
			}
		}
	}

	return $rows;
}

function is_row_exits($id)
{

	global $table;
	global $mysqli;
	global $stmt;

	$query = "SELECT id FROM {$table} WHERE id=?";

	$stmt->prepare($query);

	$stmt->bind_param('i', $id);

	$is_found = 0;

	if ($stmt->execute() && $stmt->store_result()) {
		$is_found = $stmt->affected_rows;
		$stmt->free_result();
	}

	return $is_found;
}

function set_post_stars($post_id, $score)
{

	global $table;

	global $stmt;

	$row_updated = false;

	$query = "UPDATE {$table} SET `rstar` = `rstar` + ? , `rstar_user` = `rstar_user` + 1 WHERE `id`=?";

	$stmt->prepare($query);

	$stmt->bind_param('ii', $score, $post_id);

	if ($stmt->execute()) {
		$row_updated = $stmt->affected_rows ? $stmt->affected_rows : 1;
	}

	return $row_updated;
}

function set_post_stars_cookie(&$user_review_content_cookie, &$response_list)
{
	$res = set_post_stars($_POST['post_id'], $_POST['post_score']);

	if (!$res) die(["msg" => "خطایی در ارتباط با پایگاه داده رخ داده است", "status" => 0]);

	$post = get_posts($_POST['post_id']);
	$post = end($post);
	$post = ["star"=> ($post['rstar'] / $post['rstar_user']) , "user"=> $post['rstar_user'] , "id" => $post['id']];
	
	$response_list["data"] = $post;
	$response_list["msg"] = "امتیاز {$_POST['post_score']} با موفقیت ثبت گردید";
	$response_list["status"] = 1;

	array_push($user_review_content_cookie['post_id'], $_POST['post_id']);
	setcookie("post_review_stars", json_encode($user_review_content_cookie), time() + 86400); // تا 1 روز آینده
}


فایل review-api.php جهت ساخت api لازم برای ثبت رتبه کاربران .

فایل review-api.php

<?php

header("Content-Type: application/json");
require_once "posts.php";

if (empty($_POST['post_id'])) {
	die(json_encode(["msg" => "پست آیدی ارسال نشد", "status" => 0]));
}

if (!is_row_exits($_POST['post_id'])) {
	die(json_encode(["msg" => "پست مورد نظر یافت نشد", "status" => 0]));
}

if (empty($_POST['post_score'])) {
	die(json_encode(["msg" => "امتیاز ارسال نشد", "status" => 0]));
}

$response_list = [
	"msg" => "",
	"status" => 0
];

$user_review_content_cookie = @$_COOKIE["post_review_stars"] ? $_COOKIE["post_review_stars"] : ["post_id" => []];

if (!empty($user_review_content_cookie)) {
	if(!is_array($user_review_content_cookie))
	$user_review_content_cookie = json_decode($user_review_content_cookie, true);
	if (in_array($_POST['post_id'], $user_review_content_cookie['post_id'])) {
		$response_list['msg'] = "شما از قبل به این پست امتیاز داده بودید";
	} else {
		set_post_stars_cookie($user_review_content_cookie, $response_list);
	}
} else {
	set_post_stars_cookie($user_review_content_cookie, $response_list);
	
}

die(json_encode($response_list));


style.css جهت دادن استایل به برنامه

استایل برنامه با style.css

article {
width: 25%;
border: 2px solid skyblue;
padding: 10px;
float: right;
margin-left: 15px;
}

article img {
width: 200px;
}

article h2{
    height: 82px;
}

article p{
    height: 56px;
    overflow: hidden;
}

article a {
text-decoration: none;
font-weight: bold;
background-color: #FF9800;
color: white;
width: 100%;
padding: 10px 0;
display: block;
}

.stars-wrapper{
    direction: ltr;
}

.stars-wrapper #stars-number{
    float: left;
    direction: rtl;
}

.stars-wrapper .stars-shape {
    cursor: pointer;
    transition: all 0.3s;
}

.stars-wrapper .stars-shape svg{
    overflow: initial;
    width: 15px;
    height: 15px;
    stroke-width: 55px;
    stroke: #ffc107;
    margin-left: 1px;
}
.stars-wrapper .stars-shape svg:hover{
    fill: #ffc107;
}

stop{
    stop-opacity: 1;
    stop-color: rgba(0, 0, 0, 0);
}

stop#half-stp-1{
   stop-color: #ffc107;
}


فایل app.js

document.addEventListener("DOMContentLoaded", function () {


    const starElmentDOM = document.getElementsByClassName("stars-shape");
    let requestLock = false;

    const starDOM = document.getElementsByClassName("star");
    for (var i = 0; i < starDOM.length; i++) {
        const currentElement = starDOM[i];


        currentElement.addEventListener("mouseover", handlerFillStars)

        currentElement.addEventListener("click", function (event) {

            const currentElementParent = currentElement.parentElement;
            const postID = currentElementParent.getAttribute("data-post-id");
            const score = parseInt(currentElement.getAttribute("data-item-number"));

            reviewRequest(postID, score);

        })


    }

    for (var i = 0; i < starElmentDOM.length; i++) {
        const currentElement = starElmentDOM[i];
        currentElement.addEventListener("mouseleave", handlerEmptyStars)
    }

    // handlers

    function handlerFillStars(event) {
        handlerEmptyStars();
        const currentElement = this;
        const currentElementParent = currentElement.parentElement;
        const currentElementItemNumber = currentElement.getAttribute("data-item-number");
        for (var i = 0; i < currentElementItemNumber; i++) {
            const currentElement = currentElementParent.querySelector("#star" + (i + 1));
            if (currentElement == null) continue;

            currentElement.style.fill = "#bc8f07";
        }

    }

    function handlerEmptyStars(event) {

        for (var j = 0; j < starDOM.length; j++) {
            const currentElement = starDOM[j];
            currentElement.removeAttribute("style");
        }
    }

    // ajax Request

    function reviewRequest(postID, postScore, currentElement) {

        if (requestLock)
            return;

        const xhr = new XMLHttpRequest();
        xhr.responseType = "json";

        requestLock = true;

        const params = new FormData;
        params.append("post_id", postID);
        params.append("post_score", postScore);

        xhr.open("POST", location.href + "/review-api.php");

        xhr.onload = function () {
            requestLock = false;
            const response = this.response;

            if (response.status == 1) {
     
                
                let starsNumber = response.data.star;
                const reviewerNumber = response.data.user;
                const postID = response.data.id;
                
                const starWrapper = document.querySelector("article#post-" + postID + " .stars-shape")
                
                let parentElementPreviousElement = starWrapper.previousElementSibling;
                if(!parentElementPreviousElement){
                    parentElementPreviousElement = document.createElement("span");
                    parentElementPreviousElement.id = "stars-number";
                    parentElementPreviousElement.innerHTML = '<i id="rate">x1</i> از <i id="avg-count">x2</i> رای';
                    starWrapper.parentElement.insertBefore(parentElementPreviousElement , starWrapper);
                }
                
                // مقداردهی نوشته رای
                parentElementPreviousElement.querySelector("#rate").textContent = starsNumber.toFixed(1);
                parentElementPreviousElement.querySelector("#avg-count").textContent = reviewerNumber;

                // پرکردن مجدد ستاره ها
                const svgStar = starWrapper.querySelectorAll("svg");
                
                var starTempValue = 0;
                var currentElement = null;
                for(var i=0;i<svgStar.length;i++){
                    currentElement = svgStar[i];
                    starTempValue = 1 < starsNumber ? 1 : starsNumber.toFixed(1);
                    starTempValue *= 100;
                    currentElement.querySelector("#half-stp-1").setAttribute("offset" , starTempValue + "%");
                    starsNumber--;
                }
                
            }

            alert(response.msg);
        }

        xhr.onerror = function () {
            requestLock = false;
            console.warn("[XHR Error]");
        }

        xhr.send(params);

    }
});


دموی برنامه رتبه دهی ستاره ای

قبل از اجرای برنامه وارد پوشه posts DATABASE to import شده دیتابیس را import کنید

دانلود برنامه رتبه دهی ستاره ای

ارسال نظر

جهت استفاده از کد حتما از تگ pre استفاده نمایید .

contact us