Система рейтинга
Задача:
Организовать систему рейтинга для объектов системы.
Решение:
Организуем систему рейтинга с использованием jQuery и Ajax на примере объектов каталога. В начале, необходимо отредактировать тип данных "Объект каталога". Зайдите в модуль "Шаблоны данных", найдите тип данных "Объект каталога" и откройте его для редактирования. Нажмите кнопку "Добавить группу" и задайте имя группы, например - "Рейтинг". В созданной группе добавьте два поля типа "Число":
- "Хороший" (good);
- "Плохой" (bad).
Группа полей "Рейтинг". |
Теперь необходимо написать макросы, которые будут работать с данными полями. Откройте файл "/classes/modules/vote/__custom.php" и добавьте код макросов сразу же после строки "//TODO: Write your macroses here".
Листинг 1. Код макросов установки и получения рейтинга
/*
@title
Установка рэйтинга объекта
*/
public function setRate() {
$id = (int)getRequest('id');
if(!isset($id) || !is_numeric($id))
throw new publicException('Invalid object ID');
$type = (string)getRequest('type');
if(!isset($type))
throw new publicException('Invalid rate type');
$hierarchy = umiHierarchy::getInstance();
$element = $hierarchy->getElement($id);
$rate = $element->getValue($type) + 1;
$element->setValue($type, $rate);
$element->commit();
echo $rate;
}
/*
@title
Получение рэйтинга объекта
@param Integer
$id - идентификатор объекта
@param String
$type - тип рэйтинга (good/bad)
*/
public function getRate($id, $type) {
if(!isset($id) || !is_numeric($id))
throw new publicException('Invalid object ID');
if(!isset($type))
throw new publicException('Invalid rate type');
$hierarchy = umiHierarchy::getInstance();
$element = $hierarchy->getElement($id);
$rate = $element->getValue($type);
return (int)($rate ? $rate : 0);
}
После этого, нужно добавить разрешения для макросов. Создайте файл "/classes/modules/vote/permissions.custom.php" с таким содержимым:
Листинг 2. Разрешения для макросов
<?php
$permissions = array(
'post' => array('setRate', 'getRate')
);
?>
Далее необходимо повесить обработчик на событие "click" для ссылок, по клику на которые будет устанавливаться значение рейтинга. Для этого создайте файл "/js/rate.js" и напишите в него следующий код:
Листинг 3. Обработчик события "click"
jQuery(document).ready(function() {
jQuery('.vote').click(function() {
var cid = 'vote' + jQuery(this).attr('id');
if(jQuery.cookie(cid)) {
window.alert('Вы уже голосовали!');
return false;
}
var self = jQuery(this);
var parent = jQuery(this).parent();
var id = jQuery(this).attr('id');
var type = jQuery(this).attr('name');
var req = 'id=' + id + '&type=' + type;
var e = '.rate .' + type;
parent.animate({'opacity': 0.3}, 200);
jQuery.ajax({
type: 'POST',
url: '/udata/vote/setRate',
data: req,
cache: false,
})
.success(function(data) {
self.html(data);
parent.animate({'opacity': 1}, 200);
jQuery.cookie(cid, 'true', {'expires': new Date().getTime() - 1});
})
.error(function() {
window.alert('Ошибка! К сожалению, Ваш голос не будет учтён.');
jQuery(e).animate({'opacity': 1}, 200);
});
});
jQuery('.rate .good').hover(
function() {
jQuery(this).css('background-color', '#88D135');
},
function() {
jQuery(this).css('background-color', '#4AA735');
}
);
jQuery('.rate .bad').hover(
function() {
jQuery(this).css('background-color', '#FF7A32');
},
function() {
jQuery(this).css('background-color', '#FF2926');
}
);
});
Событие "click" будет обрабатываться у ссылок с классом "vote". Также в данном коде присутствует обработчики события "hover" для кнопок установки рейтинга. Он срабатывает при наведении курсора мыши и меняет цвет кнопки. По желанию, этот функционал можно удалить.
Осталось задать стиль кнопкам установки рейтинга. Создайте файл "/css/rate.css" со следующим содержимым:
Листинг 4. Файл стилей
.rate,
.good,
.bad
{
float: left;
}
.rate
{
margin-left: 50px;
}
.good,
.bad
{
padding: 4px 12px;
text-align: center;
margin: 0 2px;
border-radius: 5px;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
}
.good a,
.bad a
{
color: #000;
font-weight: bold;
font-size: 15px;
text-decoration: none;
}
.good
{
background-color: #4AA735;
}
.bad
{
background-color: #FF2926;
}
Для примера, подключим панель рейтинга в стандартный XSLT-шаблон UMI.CMS "Интернер-магазин современный" (DemoDizzi). Откройте файл "/xsltTpls/layouts/default.xsl" и подключите созданные файлы "rate.js" и "rate.css" в секции "head" следующим образом:
Листинг 5. Подключение файлов "rate.js" и "rate.css"
<!-- rating -->
<script type="text/javascript" src="/js/rate.js"></script>
<link rel="stylesheet" type="text/css" href="/css/rate.css" />
<!-- /rating -->
После того, как файлы будут подключены, останется отредактировать шаблон вывода информации об объекте каталога. Откройте файл "/xsltTpls/modules/catalog/object-view.xsl" и разместите следующий код после блока "price", чтобы получилось примерно так:
Листинг 6. Размещение панели рейтинга в шаблоне
<!-- Блок "price" -->
<div class="price">
<span umi:element-id="{page/@id}" umi:field-name="price">
<xsl:apply-templates select="document(concat('udata://emarket/price/', page/@id))" />
</span>
</div>
<div class="rate">
<div class="good">
<a class="vote" id="{page/@id}" name="good" title="Хороший" href="javascript: void(0);">
<xsl:value-of select="document(concat('udata://vote/getRate/', page/@id, '/good/'))/udata" />
</a>
</div>
<div class="bad">
<a class="vote" id="{page/@id}" name="bad" title="Плохой" href="javascript: void(0);">
<xsl:value-of select="document(concat('udata://vote/getRate/', page/@id, '/bad/'))/udata" />
</a>
</div>
</div>
Панель рейтинга. |