Разделы

Система голосования за комментарии в Jot

Сниппет для оценки комментариев как на этом сайте.
Может быть использован для голосования за записи на стене пользователя, или комментариев к сообщению.
Создаем сниппет vote
<?php
global $modx;
$modx->db->connect();
$pid = $modx->documentIdentifier;
$ip=$_SERVER['REMOTE_ADDR'];
if(($_GET['idm']) and ($_GET['name']=='up'))
{
if((is_numeric($_GET['idm'])) and ($_GET['idm'] > 0)){
      $idm=$_GET['idm'];
      $idm = mysql_escape_String($idm);
      $ips = mysql_query("SELECT ip_add from Voting_IP where mes_id_fk='$idm' and ip_add='$ip'");
      $res = mysql_num_rows($ips);
if($res==0)
      {
      $sql = "UPDATE modx_jot_content set up=up+1 where id='$idm'";
      mysql_query( $sql); 
      $sql1 = "INSERT into Voting_IP (mes_id_fk,ip_add) values ('$idm','$ip')";
      mysql_query( $sql1);
      $modx->webAlert('Спасибо за Ваш голос','[~'.$pid.'~]');
      }
      else
      {
      $modx->webAlert('Вы уже голосовали за этот топик','[~'.$pid.'~]');
      }
}      
else
{
      $modx->webAlert('Что то Вы запрос ручками поменяли!','[~'.$pid.'~]');
}
}

if(($_GET['idm']) and ($_GET['name']=='down'))
      {
	  if((is_numeric($_GET['idm'])) and ($_GET['idm'] > 0)){
      $idm=$_GET['idm'];
      $idm = mysql_escape_String($idm);
      $ip_sql=mysql_query("select ip_add from Voting_IP where mes_id_fk='$idm' and ip_add='$ip'");
      $count=mysql_num_rows($ip_sql);
if($count==0)
      {
      $sql = "update modx_jot_content set down=down+1 where id='$idm'";
      mysql_query( $sql);
      $sql_in = "insert into Voting_IP (mes_id_fk,ip_add) values ('$idm','$ip')";
      mysql_query( $sql_in);
      $modx->webAlert('Спасибо за Ваш голос','[~'.$pid.'~]');
      }
      else
      {
      $modx->webAlert('Вы уже голосовали за этот топик','[~'.$pid.'~]');
      }  
}	  
else
{
      $modx->webAlert('Что то Вы запрос ручками поменяли!','[~'.$pid.'~]');
}
}
?>

В шаблон jot chunk.comment.inc.html добавляем
<div class='up'><a href="[~[*id*]~]?id=[+comment.id+]&name=up"  class="vote" id="[+comment.id+]" name="up"> [+comment.up:wordwrap:esc:nl2br+]</a></div>
<div class='down'><a href="[~[*id*]~]?id=[+comment.id+]&name=down" class="vote" id="[+comment.id+]" name="down">[+comment.down:wordwrap:esc:nl2br+]</a></div>

И в стили:
<style>
      .box1
      {
      float:left;
      height:80px;
      width:50px;
      }
      .up
      {
      height:20px;
      font-size:12px;
      text-align:center;
      background-color:#009900;
      margin-bottom:2px;
      -moz-border-radius: 6px;
      -webkit-border-radius: 6px;
      }
      .down
      {
      height:20px;
      font-size:12px;
      text-align:center;
      background-color:#cc0000;
      margin-top:2px;
      -moz-border-radius: 6px;
      -webkit-border-radius: 6px;
      }
</style>


И наконец добавляем в базу данных:
CREATE TABLE Voting_IP(
ip_id INT PRIMARY KEY AUTO_INCREMENT,
mes_id_fk INT,
ip_add VARCHAR(40),
FOREIGN KEY(mes_id_fk)
REFERENCES messages(mes_id));

А в таблицу modx_jot_content добавить 2 поля: up INT(10), down INT(10) со значением по умолчанию 0.
P.S. Не использовал api, Если хотите, выложу вариант с ним).
Надеюсь кому то да пригодится. Если где то в безопасности косяки, скажите мне пожалуйста. Пример

P.P.S. Поправил вывод сообщения alert и обновление страницы.
Добавил проверку GET

Комментарии (40)

RSS свернуть / развернуть
+1
avatar

alooze

  • 9 мая 2011, 16:37
0
function quote_smart($value)
{
    if (get_magic_quotes_gpc()) {
        $value = stripslashes($value);
    }
    
    if (!is_numeric($value)) {
        $value = "'" . mysql_real_escape_string($value) . "'";
    }
    return $value;
}

Вот так нормально будет?
avatar

Zinich66

  • 9 мая 2011, 16:43
0
Достаточно даже

intval($_GET['id']) == 0 ? 
avatar

alooze

  • 9 мая 2011, 16:46
0
Но мой же вариант надежнее. Как мне кажется.
avatar

Zinich66

  • 9 мая 2011, 16:51
0
Возможно надежнее. Но чем вам поможет запрос в БД

WHERE id='boo\''


если придет нечисловой id в запросе?
avatar

alooze

  • 9 мая 2011, 17:20
0
А что будет, если запрос будет не числовой? Ну добавится поле со значением id сообщения равным нолю… это же еще не критично…
avatar

Zinich66

  • 9 мая 2011, 17:25
0
Не буду превращать дискуссию в чат. Выбирайте вариант, который вам самому по душе.
avatar

alooze

  • 9 мая 2011, 17:27
0
Тогда проще сделать до всего сниппета проверку if(is_numeric($_GET['id'])){Сниппет}
avatar

Zinich66

  • 9 мая 2011, 17:28
0
А как сделать обычный лайк для страницы?
avatar

DustyArt

  • 17 мая 2011, 15:10
0
Что такое лайк?
avatar

Zinich66

  • 17 мая 2011, 16:06
0
по русски «Мне нравится»
avatar

Vopis

  • 17 мая 2011, 23:50
0
Легко. Если как в примере на сайте пойдет, могу помочь.
avatar

Zinich66

  • 18 мая 2011, 00:24
+1
global $modx;
$modx->db->connect();
$pid = $modx->documentIdentifier;
$ip=$_SERVER['REMOTE_ADDR'];
$docid = $_GET['doc_id'];

if(is_numeric($docid) & $docid>0 & !empty($_GET['type'])){
    $ip_sql = mysql_query("SELECT `ip_add` FROM `doc_ip` WHERE `doc_id_fk`='$id' AND `ip_add`='$ip'");
    $count=mysql_num_rows($ip_sql);
    if($count==0){
        if($_GET['type']=='like') mysql_query("UPDATE `modx_site_content` SET `like` = `like`+1 WHERE id='$id' ");
        if($_GET['type']=='dislike') mysql_query("UPDATE `modx_site_content` SET `dislike` = `dislike`+1 WHERE id='$id' ");
        $modx->webAlert('Спасибо за Ваш голос','[~'.$pid.'~]');
        mysql_query("INSERT INTO doc_IP (ip_add,doc_id_fk) values ('$ip','$id')");
    }
    else $modx->webAlert('Вы уже голосовали...','[~'.$pid.'~]');
}
echo "
<a href='[~[*id*]~]?doc_id=".$id."&type=like'><img src='/img/like.png'/> ".$modx->db->getValue($modx->db->select("`like`", $modx->getFullTableName('site_content'), "id=$id"))."</a>
<a href='[~[*id*]~]?doc_id=".$id."&type=dislike'><img src='/img/hate.png'/> ".$modx->db->getValue($modx->db->select("`dislike`", $modx->getFullTableName('site_content'), "id=$id"))."</a>
";


это для лайка/дизлайка документов, нужно создать два поля в modx_site_contents
(int) like
(int) dislike
avatar

Hacker

  • 23 июня 2011, 06:08
0
Это давно я делал) только в modx_site_contents ОЧЕНЬ НЕ ЖЕЛАТЕЛЬНО добавлять поля… Обновление будет через (_*_) работать. лучше, отдельная таблица с полем content_id.
avatar

Zinich66

  • 23 июня 2011, 18:55
0
А как же возможность отозвать свой голос?
if($count==1){
        if($_GET['type']=='like') mysql_query("UPDATE `modx_site_content` SET `like` = `like`-1 WHERE id='$id' ");
        if($_GET['type']=='dislike') mysql_query("UPDATE `modx_site_content` SET `dislike` = `dislike`-1 WHERE id='$id' ");
        $modx->webAlert('Спасибо за Ваш голос','[~'.$pid.'~]');
        mysql_query("DELETE FROM doc_IP WHERE ip_add = '$ip'");
    }
avatar

Zinich66

  • 23 июня 2011, 19:03
0
поторопился ты))) что же произойдет тогда если пользователь в начале поставит лайк а потом нажмёт на dislike ))) нужно запоминать в таблице тогда еще, что поставил юзер лайк или дизлайк, а на счет modx_site_contents согласен, надо будет переделать)
avatar

Hacker

  • 24 июня 2011, 16:26
+1
Точно, забыл… тогда в doc_IP еще поле сделать и писать в него $_GET['type']… а там проверять, не по 1 а по 2 параметрам) Я просто делал по принципу понравилось — голосуй, нет, ну и не надо голосовать) груба говоря как вконтакте)
avatar

Zinich66

  • 24 июня 2011, 16:32
0
Что-то не хочет засчитывать клики, всё по нулям О_о Подскажите что может быть?
avatar

Fucktor

  • 17 ноября 2011, 18:11
0
Код не меняли? Давайте адрес сайта. Посмотрю.
avatar

Zinich66

  • 26 декабря 2011, 16:25
0
та же проблема на so-roka.ru/
код не менял
avatar

Paulo

  • 26 декабря 2011, 18:12
0
А сниппет [!vote!] вызывается до или после jot?
avatar

Zinich66

  • 26 декабря 2011, 18:37
0
Выше о его вызове ничего не сказано. Ставил и до и после, никаких изменений.
avatar

Paulo

  • 26 декабря 2011, 18:47
0
В сниппете проверяется $_GET['idm'], а в шаблоне отправляется id

Вот верные ссылки:

<div class='up'><a href="[~[*id*]~]?idm=[+comment.id+]&name=up"  class="vote" id="[+comment.id+]" name="up"> [+comment.up:wordwrap:esc:nl2br+]</a></div>
<div class='down'><a href="[~[*id*]~]?idm=[+comment.id+]&name=down" class="vote" id="[+comment.id+]" name="down">[+comment.down:wordwrap:esc:nl2br+]</a></div>
avatar

bezumkin

  • 5 января 2012, 14:04
0
Спасибо за замечание :)
avatar

Zinich66

  • 5 января 2012, 14:42
0
Добавил возможность запросов по Ajax

<?php
$modx->db->connect();
$pid = $modx->documentIdentifier;

$ip = $_SERVER['REMOTE_ADDR'];

if (!empty($_GET['idm']) && $_GET['idm'] > 0) {
   $idm = mysql_escape_string($_GET['idm']);

   $ips = mysql_query("SELECT `ip_add` from `Voting_IP` where `mes_id_fk` = '$idm' and `ip_add` = '$ip'");
   $res = mysql_num_rows($ips);

    if ($res == 0) {
        if ($_GET['name'] == 'up') {
          mysql_query("UPDATE `modx_jot_content` set `up` = up+1 where `id` = '$idm'");
          $value = mysql_result(mysql_query("SELECT `up` FROM `modx_jot_content` WHERE `id` = '$idm'"), 0, 0);
        }
        else if ($_GET['name'] == 'down') {
          mysql_query("UPDATE `modx_jot_content` set `down` = down+1 where `id` = '$idm'");
          $value = mysql_result(mysql_query("SELECT `down` FROM `modx_jot_content` WHERE `id` = '$idm'"), 0, 0);
        }
        
        mysql_query("INSERT into `Voting_IP` (`mes_id_fk`, `ip_add`) values ('$idm', '$ip')");
        $arr = array('status' => 'success', 'message' => 'Ваш голос принят', 'value' => $value);
    }
    else {
        $arr = array('status' => 'error', 'message' => 'Вы уже голосовали за этот комментарий');
    }
    
    // Принято через Ajax
    if ($_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest')  {
        echo json_encode($arr);
        die;
    }
    // Обычный запрос
    else {
        if ($arr['status'] == 'error') {
            $modx->webAlert($arr['message'], '[~'.$pid.'~]');
        }
    }
    
}
?>
avatar

bezumkin

  • 5 января 2012, 18:14
0
jQuery код для обработки нажатия и результатов
$(document).ready(function() {
	$('.voteBox a').live('click', function() {
		var elem = $(this);
		var idm = $(this).data('idm');
		var name = $(this).data('name');
		$.get(document.location.href, {idm: idm, name: name}, function(data) {
			var res = $.parseJSON(data)
			if (res.status == 'success') {
				$(elem).text(res.value);
				alert(res.message);
			}
			else {
				alert(res.message);
			}
		})
		return false;
	})
})
avatar

bezumkin

  • 5 января 2012, 20:22
0
Ссылки для голосования в чанке vhunk.comment.inc.html
<div class="voteBox">
<div class='up'><a href="[~[*id*]~]?idm=[+comment.id+]&name=up"  class="vote" id="[+comment.id+]" data-idm="[+comment.id+]" data-name="up"> [+comment.up:wordwrap:esc:nl2br+]</a></div>
<div class='down'><a href="[~[*id*]~]?idm=[+comment.id+]&name=down" class="vote" id="[+comment.id+]" data-idm="[+comment.id+]" data-name="down">[+comment.down:wordwrap:esc:nl2br+]</a></div>
</div>

Добавились два параметра для работы ajax: data-idm="[+comment.id+]" и data-name=«up\down»

Сниппет может обрабатывать голосование и через ajax и обычным $_GET запросом.
avatar

bezumkin

  • 5 января 2012, 20:26
0
у меня фаербаг выдает

res is null
if (res.status == 'success') {

че делать?
avatar

Lisjann

  • 17 января 2012, 17:23
+1
$.get(document.location.href, {idm: idm, name: name}, function(data) {
alert(data)
var res = $.parseJSON(data)


Что вообще от php приходит? Что в алерте?
avatar

bezumkin

  • 17 января 2012, 19:15
0
делал для AJAX все что для php заменил код в сниппете [!vote!], jQuery вставил повыше вывода сниппета [!Jot? &moderated=`1` !] и ссылки для голосования закинул в шаблон. Вопрос еще куда вставлять [!vote!]? я вставил ниже [!Jot!]

<script type="text/javascript">
		$(document).ready(function() {
	$('.voteBox a').live('click', function() {
		var elem = $(this);
		var idm = $(this).data('idm');
		var name = $(this).data('name');
		$.get(document.location.href, {idm: idm, name: name}, function(data) {
			var res = $.parseJSON(data)
			if (res.status == 'success') {
				$(elem).text(res.value);
				alert(res.message);
			}
			else {
				alert(res.message);
			}
		})
		return false;
	})
})		
</script>
[!Jot? &moderated=`1` !]	
[[vote]]

вот так вот
avatar

Lisjann

  • 18 января 2012, 13:22
0
поразбирался, понял что чтобы увидить добавленный голос нужно перенрузить страницу, как томожно чтобсразу нажал и голос добавился
avatar

Lisjann

  • 18 января 2012, 18:01
0
Конечно можно.
$(elem).text(res.value);
Это и делается…
avatar

Zinich66

  • 18 января 2012, 18:49
0
Или у вас голосование при клике не на сам голос а на кнопку рядом?
avatar

Zinich66

  • 18 января 2012, 18:50
0
нет на сам голос нажимать, я как понял у меня функция не работает

function(data) {
var res = $.parseJSON(data);
if (res.status == 'success') {
$(elem).text(res.value);
alert(res.message);
}
else {
alert(res.message);
}
})
return false;

фаербаг выдает

res is null
if (res.status == 'success') {

хотя гет запрос через аякс проходит и пхп тоже адекватно работает
и вообще что значит это условие я не понял
avatar

Lisjann

  • 18 января 2012, 19:07
0
может еще какойнить фал надо установить для JSON
avatar

Lisjann

  • 18 января 2012, 19:21
0
Прошу пожалуйста помогите разобаться!!! почему у меня условие выдает ошибку?
avatar

Lisjann

  • 19 января 2012, 13:43
+1
Нафига $modx->db->connect()?
avatar

antonkuzmin

  • 18 января 2012, 19:12
0
токо что проверил, без него работает!!!
avatar

Lisjann

  • 18 января 2012, 19:14
0
Так Вы наверное сниппетом… А я то изначально файлом… поэтому и
global $modx;
avatar

Zinich66

  • 18 января 2012, 21:02
0
А код не чистил, когда кидал…
avatar

Zinich66

  • 18 января 2012, 21:03

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.