Оценка документов ГД

2 views
Skip to first unread message

ButscH

unread,
Jun 6, 2008, 4:03:40 AM6/6/08
to Open Constructor
Итак у вас есть задача сделать оценку документов ГД.

Приступим. За основу я взял http://www.masugadesign.com/the-lab/scripts/unobtrusive-ajax-star-rating-bar/
вот этот рейтинг. Только в моем случае есть некоторое отличие.

Для начала скачайте у них исходники, они нам нужны будут

Создаем у ГД три поля: ip - примитивный тип - текст; total_votes -
string (4); total_value - string (4);
Думаю этого хватит.

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

В css добавляем стили из архива. И кидаем картинки в папку с
изоброжениями. И правим в стилях пути. НЕ забываем все привязать к
сайту.

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Добавляем в хеад ява скрипты из скаченного архива на страницу где
будете ииспользовать.
<script type="text/javascript" language="javascript" src="/res/js/
behavior.js"></script>
<script type="text/javascript" language="javascript" src="/res/js/
rating.js"></script>
behavior.js - нужно немного подправить

var Behaviour = {
list : new Array,

register : function(sheet){
Behaviour.list.push(sheet);
},

start : function(){
Behaviour.addLoadEvent(function(){
Behaviour.apply();
});
},

apply : function(){
for (h=0;sheet=Behaviour.list[h];h++){
for (selector in sheet){
list = document.getElementsBySelector(selector);

if (!list){
continue;
}

for (i=0;element=list[i];i++){
sheet[selector](element);
}
}
}
},

addLoadEvent : function(func){
var oldonload = window.onload;

if (typeof window.onload != 'function') {
window.onload = func;
} else {
window.onload = function() {
oldonload();
func();
}
}
}
}

Behaviour.start();

function getAllChildren(e) {
// Returns all children of element. Workaround required for IE5/
Windows. Ugh.
return e.all ? e.all : e.getElementsByTagName('*');
}

document.getElementsBySelector = function(selector) {
// Attempt to fail gracefully in lesser browsers
if (!document.getElementsByTagName) {
return new Array();
}
// Split selector in to tokens
var tokens = selector.split(' ');
var currentContext = new Array(document);
for (var i = 0; i < tokens.length; i++) {
token = tokens[i].replace(/^\s+/,'').replace(/\s+$/,'');;
if (token.indexOf('#') > -1) {
// Token is an ID selector
var bits = token.split('#');
var tagName = bits[0];
var id = bits[1];
var element = document.getElementById(id);
if (tagName && element.nodeName.toLowerCase() != tagName) {
// tag with that ID not found, return false
return new Array();
}
// Set currentContext to contain just this element
currentContext = new Array(element);
continue; // Skip to next token
}
if (token.indexOf('.') > -1) {
// Token contains a class selector
var bits = token.split('.');
var tagName = bits[0];
var className = bits[1];
if (!tagName) {
tagName = '*';
}
// Get elements matching tag, filter them for class selector
var found = new Array;
var foundCount = 0;
for (var h = 0; h < currentContext.length; h++) {
var elements;
if (tagName == '*') {
elements = getAllChildren(currentContext[h]);
} else {
elements =
currentContext[h].getElementsByTagName(tagName);
}
for (var j = 0; j < elements.length; j++) {
found[foundCount++] = elements[j];
}
}
currentContext = new Array;
var currentContextIndex = 0;
for (var k = 0; k < found.length; k++) {
if (found[k].className && found[k].className.match(new
RegExp('\\b'+className+'\\b'))) {
currentContext[currentContextIndex++] = found[k];
}
}
continue; // Skip to next token
}
// Code to deal with attribute selectors
if (token.match(/^(\w*)\[(\w+)([=~\|\^\$\*]?)=?"?([^\]"]*)"?\]$/))
{
var tagName = RegExp.$1;
var attrName = RegExp.$2;
var attrOperator = RegExp.$3;
var attrValue = RegExp.$4;
if (!tagName) {
tagName = '*';
}
// Grab all of the tagName elements within current context
var found = new Array;
var foundCount = 0;
for (var h = 0; h < currentContext.length; h++) {
var elements;
if (tagName == '*') {
elements = getAllChildren(currentContext[h]);
} else {
elements =
currentContext[h].getElementsByTagName(tagName);
}
for (var j = 0; j < elements.length; j++) {
found[foundCount++] = elements[j];
}
}
currentContext = new Array;
var currentContextIndex = 0;
var checkFunction; // This function will be used to filter the
elements
switch (attrOperator) {
case '=': // Equality
checkFunction = function(e) { return
(e.getAttribute(attrName) == attrValue); };
break;
case '~': // Match one of space seperated words
checkFunction = function(e) { return
(e.getAttribute(attrName).match(new RegExp('\\b'+attrValue+'\
\b'))); };
break;
case '|': // Match start with value followed by optional
hyphen
checkFunction = function(e) { return
(e.getAttribute(attrName).match(new RegExp('^'+attrValue+'-?'))); };
break;
case '^': // Match starts with value
checkFunction = function(e) { return
(e.getAttribute(attrName).indexOf(attrValue) == 0); };
break;
case '$': // Match ends with value - fails with "Warning" in
Opera 7
checkFunction = function(e) { return
(e.getAttribute(attrName).lastIndexOf(attrValue) ==
e.getAttribute(attrName).length - attrValue.length); };
break;
case '*': // Match ends with value
checkFunction = function(e) { return
(e.getAttribute(attrName).indexOf(attrValue) > -1); };
break;
default :
// Just test for existence of attribute
checkFunction = function(e) { return
e.getAttribute(attrName); };
}
currentContext = new Array;
var currentContextIndex = 0;
for (var k = 0; k < found.length; k++) {
if (checkFunction(found[k])) {
currentContext[currentContextIndex++] = found[k];
}
}
// alert('Attribute Selector: '+tagName+' '+attrName+'
'+attrOperator+' '+attrValue);
continue; // Skip to next token
}

if (!currentContext[0]){
return;
}

// If we get here, token is JUST an element (not a class or ID
selector)
tagName = token;
var found = new Array;
var foundCount = 0;
for (var h = 0; h < currentContext.length; h++) {
var elements = currentContext[h].getElementsByTagName(tagName);
for (var j = 0; j < elements.length; j++) {
found[foundCount++] = elements[j];
}
}
currentContext = found;
}
return currentContext;
}


/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


Далее на страницу с ГД ставим php код в блок PRE:

<?

function rating_bar($id,$units='',$static='') {

global $ctx;
$db = $ctx->_getDB();
$id = $ctx->getParam('article');

$rating_unitwidth = 30;

//set some variables
$ip = $_SERVER['REMOTE_ADDR'];
if (!$units) {$units = 10;}
if (!$static) {$static = FALSE;}

// get votes, values, ips for the current rating bar
$query = $db->query("SELECT f_total_votes, f_total_value, f_ip FROM
dshybrid_12 WHERE id='$id' ");

if (mysql_num_rows($query) == 0) {
$result = $db->query("INSERT INTO dshybrid_12 (`id`, `f_total_votes`,
`f_total_value`, `f_ip`) VALUES ('$id', '0', '0', '')");
}

$numbers=mysql_fetch_assoc($query);


if ($numbers['f_total_votes'] < 1) {
$count = 0;
} else {
$count=$numbers['f_total_votes']; //how many votes total
}
$current_rating=$numbers['f_total_value']; //total number of rating
added together and stored
$tense=($count==1) ? "голос" : "голосов"; //plural form votes/vote

// determine whether the user has voted, so we know how to draw the ul/
li
$voted=mysql_num_rows(mysql_query("SELECT f_ip FROM dshybrid_12 WHERE
f_ip LIKE '%".$ip."%' AND id='".$id."' "));

// now draw the rating bar
$rating_width = @number_format($current_rating/$count,2)*
$rating_unitwidth;
$rating1 = @number_format($current_rating/$count,1);
$rating2 = @number_format($current_rating/$count,2);


if ($static == 'static') {

$static_rater = array();
$static_rater[] .= "\n".'<div class="ratingblock">';
$static_rater[] .= '<div id="unit_long'.$id.'">';
$static_rater[] .= '<ul id="unit_ul'.$id.'" class="unit-rating"
style="width:'.$rating_unitwidth*$units.'px;">';
$static_rater[] .= '<li class="current-rating" style="width:'.
$rating_width.'px;">Currently '.$rating2.'/'.$units.'</li>';
$static_rater[] .= '</ul>';
$static_rater[] .= '<p class="static">'.$id.'. Рейтинг: <strong> '.
$rating1.'</strong>/'.$units.' ('.$count.' '.$tense.' ) <em>This is
\'static\'.</em></p>';
$static_rater[] .= '</div>';
$static_rater[] .= '</div>'."\n\n";

return join("\n", $static_rater);


} else {

$rater ='';
$rater.='<div class="ratingblock">';

$rater.='<div id="unit_long'.$id.'">';
$rater.=' <ul id="unit_ul'.$id.'" class="unit-rating"
style="width:'.$rating_unitwidth*$units.'px;">';
$rater.=' <li class="current-rating" style="width:'.
$rating_width.'px;">Currently '.$rating2.'/'.$units.'</li>';

for ($ncount = 1; $ncount <= $units; $ncount++) { // loop from 1
to the number of units
if(!$voted) { // if the user hasn't yet voted, draw the
voting stars
$rater.='<li><a href="/news/index.php/article/.'.$id.'/
rate/?j='.$ncount.'&amp;q='.$id.'&amp;t='.$ip.'&amp;c='.$units.'"
title="'.$ncount.' из '.$units.'" class="r'.$ncount.'-unit rater"
rel="nofollow">'.$ncount.'</a></li>';
}
}
$ncount=0; // resets the count

$rater.=' </ul>';
$rater.=' <p';
if($voted){ $rater.=' class="voted"'; }
$rater.='>Рейтинг: <strong> '.$rating1.'</strong>/'.$units.' ('.
$count.' '.$tense.' )';
$rater.=' </p>';
$rater.='</div>';
$rater.='</div>';
return $rater;
}
}
global $ctx;
$id = $ctx->getParam('article');
$ctx->setParam('ratings',rating_bar('$id',''));
?>

И вызываем на этой же странице в ГД {$ctx->getParam('ratings')}
Итак после этого на странице должны появится звезды.


/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


Теперь разберемся со страницей обработчиком. В моем случае она /news/
index.php/article/rate/

Вот php код для нее: Кидаем в блок PRE
<?php

global $ctx;
$db = $ctx->_getDB();

header("Cache-Control: no-cache");
header("Pragma: nocache");

$vote_sent = preg_replace("/[^0-9]/","",$_REQUEST['j']);
$id_sent = preg_replace("/[^0-9a-zA-Z]/","",$_REQUEST['q']);
$ip_num = preg_replace("/[^0-9\.]/","",$_REQUEST['t']);
$units = preg_replace("/[^0-9]/","",$_REQUEST['c']);
$ip = $_SERVER['REMOTE_ADDR'];
$referer = $_SERVER['REFERER'];

if ($vote_sent > $units) die("Sorry, vote appears to be invalid."); //
kill the script because normal users will never see this.

//connecting to the database to get some information
$query = $db->query("SELECT f_total_votes, f_total_value, f_ip FROM
dshybrid_12 WHERE id='$id_sent' ",$dbsel);
$numbers = mysql_fetch_assoc($query);
$checkIP = unserialize($numbers['f_ip']);
$count = $numbers['f_total_votes']; //how many votes total
$current_rating = $numbers['f_total_value']; //total number of rating
added together and stored
$sum = $vote_sent+$current_rating; // add together the current vote
value and the total vote value
$tense = ($count==1) ? "vote" : "votes"; //plural form votes/vote

// checking to see if the first vote has been tallied
// or increment the current number of votes
($sum==0 ? $added=0 : $added=$count+1);

// if it is an array i.e. already has entries the push in another
value
((is_array($checkIP)) ? array_push($checkIP,$ip_num) :
$checkIP=array($ip_num));
$insertip=serialize($checkIP);

//IP check when voting
$voted=mysql_num_rows($db->query("SELECT f_ip FROM dshybrid_12 WHERE
f_ip LIKE '%".$ip."%' AND id='".$id_sent."' "));
if(!$voted) { //if the user hasn't yet voted, then vote
normally...


if (($vote_sent >= 1 && $vote_sent <= $units) && ($ip == $ip_num))
{ // keep votes within range
$update = "UPDATE dshybrid_12 SET f_total_votes='".$added."',
f_total_value='".$sum."', f_ip='".$insertip."' WHERE id='$id_sent'";
$result = $db->query($update);
}

//header("Location: $referer"); // go back to the page we came from

} //end for the "if(!$voted)"

sendRedirect ("/news/index.php/article/.$id_sent/");
?>


/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


Так теперь осталось вам подправить все пути и id на свои ГД заменить и
все должно заработать.
Пример http://www.butsch.ru/news/index.php/article/.316/
Reply all
Reply to author
Forward
0 new messages