1
0
Fork 0
mirror of https://github.com/Oreolek/ifhub.club.git synced 2024-05-17 08:18:18 +03:00

добавлена поддержка топика-вопроса

This commit is contained in:
Mzhelskiy Maxim 2008-10-01 18:53:51 +00:00
parent 74f1ae7856
commit 04214078f6
13 changed files with 348 additions and 21 deletions

View file

@ -113,7 +113,7 @@ class ActionLink extends Action {
* Меню
*/
$this->sMenuSubItemSelect='';
$this->sMenuItemSelect='';
$this->sMenuItemSelect='link';
/**
* Получаем номер топика из УРЛ и проверяем существует ли он
*/

View file

@ -653,5 +653,23 @@ class Topic extends Module {
public function GetDateRead($sTopicId,$sUserId) {
return $this->oMapperTopic->GetDateRead($sTopicId,$sUserId);
}
/**
* Проверяет голосовал ли юзер за топик-вопрос
*
* @param unknown_type $sTopicId
* @param unknown_type $sUserId
* @return unknown
*/
public function GetTopicQuestionVote($sTopicId,$sUserId) {
return $this->oMapperTopic->GetTopicQuestionVote($sTopicId,$sUserId);
}
/**
* Добавляет факт голосования за топик-вопрос
*
* @param TopicEntity_TopicQuestionVote $oTopicQuestionVote
*/
public function AddTopicQuestionVote(TopicEntity_TopicQuestionVote $oTopicQuestionVote) {
return $this->oMapperTopic->AddTopicQuestionVote($oTopicQuestionVote);
}
}
?>

View file

@ -123,7 +123,9 @@ class TopicEntity_Topic extends Entity
public function getUserVoteDelta() {
return $this->_aData['user_vote_delta'];
}
public function getUserQuestionIsVote() {
return $this->_aData['user_question_is_vote'];
}
/***************************************************************************************************************************************************
@ -136,7 +138,7 @@ class TopicEntity_Topic extends Entity
$this->aExtra=unserialize($this->getExtra());
}
}
// методы для топика-ссылки
public function getLinkUrl($bShort=false) {
if ($this->getType()!='link') {
return null;
@ -182,9 +184,90 @@ class TopicEntity_Topic extends Entity
$this->aExtra['count_jump']=$data;
$this->setExtra($this->aExtra);
}
//методы для топика-вопроса
public function addQuestionAnswer($data) {
if ($this->getType()!='question') {
return;
}
$this->extractExtra();
$this->aExtra['answers'][]=array('text'=>$data,'count'=>0);
$this->setExtra($this->aExtra);
}
public function clearQuestionAnswer() {
if ($this->getType()!='question') {
return;
}
$this->extractExtra();
$this->aExtra['answers']=array();
$this->setExtra($this->aExtra);
}
public function getQuestionAnswers() {
if ($this->getType()!='question') {
return null;
}
$this->extractExtra();
if (isset($this->aExtra['answers'])) {
return $this->aExtra['answers'];
}
return array();
}
public function increaseQuestionAnswerVote($sIdAnswer) {
if ($aAnswers=$this->getQuestionAnswers()) {
if (isset($aAnswers[$sIdAnswer])) {
$aAnswers[$sIdAnswer]['count']++;
$this->aExtra['answers']=$aAnswers;
$this->setExtra($this->aExtra);
}
}
}
public function getQuestionAnswerPercent($sIdAnswer) {
if ($aAnswers=$this->getQuestionAnswers()) {
if (isset($aAnswers[$sIdAnswer])) {
$iCountAll=$this->getQuestionCountVote()-$this->getQuestionCountVoteAbstain();
if ($iCountAll==0) {
return 0;
} else {
return round($aAnswers[$sIdAnswer]['count']*100/$iCountAll,2);
}
}
}
}
public function getQuestionCountVote() {
if ($this->getType()!='question') {
return null;
}
$this->extractExtra();
if (isset($this->aExtra['count_vote'])) {
return (int)$this->aExtra['count_vote'];
}
return 0;
}
public function setQuestionCountVote($data) {
if ($this->getType()!='question') {
return;
}
$this->extractExtra();
$this->aExtra['count_vote']=$data;
$this->setExtra($this->aExtra);
}
public function getQuestionCountVoteAbstain() {
if ($this->getType()!='question') {
return null;
}
$this->extractExtra();
if (isset($this->aExtra['count_vote_abstain'])) {
return (int)$this->aExtra['count_vote_abstain'];
}
return 0;
}
public function setQuestionCountVoteAbstain($data) {
if ($this->getType()!='question') {
return;
}
$this->extractExtra();
$this->aExtra['count_vote_abstain']=$data;
$this->setExtra($this->aExtra);
}

View file

@ -121,7 +121,8 @@ class Mapper_Topic extends Mapper {
b.blog_url as blog_url,
b.blog_title as blog_title,
IF(tv.topic_id IS NULL,0,1) as user_is_vote,
tv.vote_delta as user_vote_delta
tv.vote_delta as user_vote_delta,
IF(tqv.topic_id IS NULL,0,1) as user_question_is_vote
FROM
".DB_TABLE_TOPIC." as t
@ -131,7 +132,14 @@ class Mapper_Topic extends Mapper {
vote_delta
FROM ".DB_TABLE_TOPIC_VOTE."
WHERE user_voter_id = ?d
) AS tv ON tv.topic_id = t.topic_id,
) AS tv ON tv.topic_id = t.topic_id
LEFT JOIN (
SELECT
topic_id
FROM ".DB_TABLE_TOPIC_QUESTION_VOTE."
WHERE user_voter_id = ?d
) AS tqv ON tqv.topic_id = t.topic_id,
".DB_TABLE_USER." as u,
".DB_TABLE_BLOG." as b
@ -158,7 +166,8 @@ class Mapper_Topic extends Mapper {
b.blog_url as blog_url,
b.blog_title as blog_title,
IF(tv.topic_id IS NULL,0,1) as user_is_vote,
tv.vote_delta as user_vote_delta
tv.vote_delta as user_vote_delta,
IF(tqv.topic_id IS NULL,0,1) as user_question_is_vote
FROM
(
SELECT
@ -182,9 +191,15 @@ class Mapper_Topic extends Mapper {
FROM ".DB_TABLE_TOPIC_VOTE."
WHERE user_voter_id = ?d
) AS tv ON t_fast.topic_id=tv.topic_id
LEFT JOIN (
SELECT
topic_id
FROM ".DB_TABLE_TOPIC_QUESTION_VOTE."
WHERE user_voter_id = ?d
) AS tqv ON t_fast.topic_id=tqv.topic_id
JOIN ".DB_TABLE_TOPIC_CONTENT." AS tc ON t_fast.topic_id=tc.topic_id
";
if ($aRow=$this->oDb->selectRow($sql,$sId,$iPublish,$iCurrentUserId)) {
if ($aRow=$this->oDb->selectRow($sql,$sId,$iPublish,$iCurrentUserId,$iCurrentUserId)) {
return new TopicEntity_Topic($aRow);
}
return null;
@ -249,7 +264,8 @@ class Mapper_Topic extends Mapper {
tc.*,
u.user_login as user_login,
IF(tv.topic_id IS NULL,0,1) as user_is_vote,
tv.vote_delta as user_vote_delta
tv.vote_delta as user_vote_delta,
IF(tqv.topic_id IS NULL,0,1) as user_question_is_vote
FROM (
SELECT
t.*,
@ -277,12 +293,18 @@ class Mapper_Topic extends Mapper {
FROM ".DB_TABLE_TOPIC_VOTE."
WHERE user_voter_id = ?d
) AS tv ON t_fast.topic_id=tv.topic_id
LEFT JOIN (
SELECT
topic_id
FROM ".DB_TABLE_TOPIC_QUESTION_VOTE."
WHERE user_voter_id = ?d
) AS tqv ON t_fast.topic_id=tqv.topic_id
JOIN ".DB_TABLE_TOPIC_CONTENT." AS tc ON t_fast.topic_id=tc.topic_id
;
";
$aTopics=array();
if ($aRows=$this->oDb->select($sql,($iCurrPage-1)*$iPerPage, $iPerPage, $iCurrentUserId)) {
if ($aRows=$this->oDb->select($sql,($iCurrPage-1)*$iPerPage, $iPerPage, $iCurrentUserId,$iCurrentUserId)) {
foreach ($aRows as $aTopic) {
$aTopics[]=new TopicEntity_Topic($aTopic);
}
@ -368,7 +390,8 @@ class Mapper_Topic extends Mapper {
b.blog_type as blog_type,
b.blog_url as blog_url,
IF(tv.topic_id IS NULL,0,1) as user_is_vote,
tv.vote_delta as user_vote_delta
tv.vote_delta as user_vote_delta,
IF(tqv.topic_id IS NULL,0,1) as user_question_is_vote
FROM (
SELECT
topic_id
@ -389,12 +412,18 @@ class Mapper_Topic extends Mapper {
FROM ".DB_TABLE_TOPIC_VOTE."
WHERE user_voter_id = ?d
) AS tv ON tt.topic_id=tv.topic_id
LEFT JOIN (
SELECT
topic_id
FROM ".DB_TABLE_TOPIC_QUESTION_VOTE."
WHERE user_voter_id = ?d
) AS tqv ON tt.topic_id=tqv.topic_id
LEFT JOIN ".DB_TABLE_TOPIC_CONTENT." AS tc ON tt.topic_id=tc.topic_id
;
";
$aTopics=array();
if ($aRows=$this->oDb->select($sql,$sTag,($iCurrPage-1)*$iPerPage, $iPerPage,$iCurrentUserId)) {
if ($aRows=$this->oDb->select($sql,$sTag,($iCurrPage-1)*$iPerPage, $iPerPage,$iCurrentUserId,$iCurrentUserId)) {
foreach ($aRows as $aTopic) {
$aTopics[]=new TopicEntity_Topic($aTopic);
}
@ -466,7 +495,8 @@ class Mapper_Topic extends Mapper {
tc.*,
u.user_login as user_login,
IF(tv.topic_id IS NULL,0,1) as user_is_vote,
tv.vote_delta as user_vote_delta
tv.vote_delta as user_vote_delta,
IF(tqv.topic_id IS NULL,0,1) as user_question_is_vote
FROM (
SELECT
t.*,
@ -497,11 +527,17 @@ class Mapper_Topic extends Mapper {
FROM ".DB_TABLE_TOPIC_VOTE."
WHERE user_voter_id = ?d
) AS tv ON t_fast.topic_id=tv.topic_id
LEFT JOIN (
SELECT
topic_id
FROM ".DB_TABLE_TOPIC_QUESTION_VOTE."
WHERE user_voter_id = ?d
) AS tqv ON t_fast.topic_id=tqv.topic_id
JOIN ".DB_TABLE_TOPIC_CONTENT." AS tc ON t_fast.topic_id=tc.topic_id
";
$aTopics=array();
if ($aRows=$this->oDb->select($sql,$sDate,$iLimit,$iCurrentUserId)) {
if ($aRows=$this->oDb->select($sql,$sDate,$iLimit,$iCurrentUserId,$iCurrentUserId)) {
foreach ($aRows as $aTopic) {
$aTopics[]=new TopicEntity_Topic($aTopic);
}
@ -823,5 +859,28 @@ class Mapper_Topic extends Mapper {
}
return false;
}
public function AddTopicQuestionVote(TopicEntity_TopicQuestionVote $oTopicQuestionVote) {
$sql = "INSERT INTO ".DB_TABLE_TOPIC_QUESTION_VOTE."
(topic_id,
user_voter_id,
answer
)
VALUES(?d, ?d, ?f)
";
if ($this->oDb->query($sql,$oTopicQuestionVote->getTopicId(),$oTopicQuestionVote->getVoterId(),$oTopicQuestionVote->getAnswer())===0)
{
return true;
}
return false;
}
public function GetTopicQuestionVote($sTopicId,$sUserId) {
$sql = "SELECT * FROM ".DB_TABLE_TOPIC_QUESTION_VOTE." WHERE topic_id = ?d and user_voter_id = ?d ";
if ($aRow=$this->oDb->selectRow($sql,$sTopicId,$sUserId)) {
return new TopicEntity_TopicQuestionVote($aRow);
}
return null;
}
}
?>

View file

@ -40,6 +40,7 @@ return array(
'talk' => 'ActionTalk',
'rss' => 'ActionRss',
'link' => 'ActionLink',
'question' => 'ActionQuestion',
),
'config' => array(
'action_default' => 'index',

View file

@ -38,4 +38,5 @@ define('DB_TABLE_TALK_USER',DB_PREFIX_TABLE.'talk_user');
define('DB_TABLE_TALK_COMMENT',DB_PREFIX_TABLE.'talk_comment');
define('DB_TABLE_FREND',DB_PREFIX_TABLE.'frend');
define('DB_TABLE_TOPIC_CONTENT',DB_PREFIX_TABLE.'topic_content');
define('DB_TABLE_TOPIC_QUESTION_VOTE',DB_PREFIX_TABLE.'topic_question_vote');
?>

View file

@ -19,6 +19,34 @@ ALTER TABLE `prefix_topic_content`
--
-- Структура таблицы `prefix_topic_question_vote`
--
CREATE TABLE IF NOT EXISTS `prefix_topic_question_vote` (
`topic_id` int(11) unsigned NOT NULL,
`user_voter_id` int(11) unsigned NOT NULL,
`answer` tinyint(4) NOT NULL,
UNIQUE KEY `topic_id_user_id` (`topic_id`,`user_voter_id`),
KEY `topic_id` (`topic_id`),
KEY `user_voter_id` (`user_voter_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
--
-- Ограничения внешнего ключа сохраненных таблиц
--
--
-- Ограничения внешнего ключа таблицы `prefix_topic_question_vote`
--
ALTER TABLE `prefix_topic_question_vote`
ADD CONSTRAINT `prefix_topic_question_vote_fk1` FOREIGN KEY (`user_voter_id`) REFERENCES `prefix_user` (`user_id`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `prefix_topic_question_vote_fk` FOREIGN KEY (`topic_id`) REFERENCES `prefix_topic` (`topic_id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- Меняем индекс в таблице комментов
ALTER TABLE `prefix_topic_comment` DROP INDEX `comment_date_rating` ;
ALTER TABLE `prefix_topic_comment` ADD INDEX `rating_date_id` ( `comment_rating` , `comment_date` , `comment_id` ) ;

View file

@ -116,4 +116,40 @@ div.comment_text2 {
margin-top:3px;
font-family:Arial;
background:#e7eefe;
}
/*Опросы*/
.poll dl {
float: left;
clear: both;
width: 100%;
border: .5em solid #fff;
margin: 0px 0px 0px 0px;
}
.poll dl dt {
float: left;
width: 8%;
font-size: 97.6%;
text-align: right;
margin-left: -20px;
color: #ccc;
}
.poll dl dt strong {
color:#404040;
text-align: right;
}
.poll dl dd {
width: 91%;
float: left;
margin-left: 20px;
}
.poll .total {
font-size: 97.6%;
clear: both;
margin-top: 1em;
color: #999;
}

View file

@ -10,7 +10,7 @@
<LINK media=all href="{$DIR_STATIC_SKIN}/css/habrahabr.css?v=1" type=text/css rel=stylesheet>
<LINK media=all href="{$DIR_STATIC_SKIN}/css/backoffice.css?v=2" type=text/css rel=stylesheet>
<LINK media=all href="{$DIR_STATIC_SKIN}/css/global.css?v=4" type=text/css rel=stylesheet>
<LINK media=all href="{$DIR_STATIC_SKIN}/css/my.css?v=2" type=text/css rel=stylesheet>
<LINK media=all href="{$DIR_STATIC_SKIN}/css/my.css?v=3" type=text/css rel=stylesheet>
<LINK media=all href="{$DIR_STATIC_SKIN}/css/Roar.css" type=text/css rel=stylesheet>
<LINK media=all href="{$DIR_STATIC_SKIN}/css/Autocompleter.css" type=text/css rel=stylesheet>
</HEAD>
@ -22,7 +22,7 @@
<script type="text/javascript" src="{$DIR_WEB_ROOT}/classes/lib/external/MooTools_1.2/plugs/Autocompleter/Autocompleter.js"></script>
<script type="text/javascript" src="{$DIR_WEB_ROOT}/classes/lib/external/MooTools_1.2/plugs/Autocompleter/Autocompleter.Request.js"></script>
<script type="text/javascript" src="{$DIR_WEB_ROOT}/classes/lib/external/MooTools_1.2/plugs/Autocompleter/Observer.js"></script>
<script type="text/javascript" src="{$DIR_STATIC_SKIN}/js/main.js?v=9"></script>
<script type="text/javascript" src="{$DIR_STATIC_SKIN}/js/main.js?v=10"></script>
<BODY>
{literal}

View file

@ -183,6 +183,27 @@ function ajaxBlogInfo(idBlog) {
req.send( { idBlog: idBlog } );
}
function ajaxQuestionVote(idTopic,idAnswer) {
var req = new JsHttpRequest();
req.onreadystatechange = function() {
if (req.readyState == 4) {
document.getElementById('debug').innerHTML = req.responseText;
closeWindowStatus();
if (req.responseJS.bStateError) {
msgErrorBox.alert(req.responseJS.sMsgTitle,req.responseJS.sMsg);
} else {
msgNoticeBox.alert(req.responseJS.sMsgTitle,req.responseJS.sMsg);
if (document.getElementById('topic_question_area_'+idTopic)) {
document.getElementById('topic_question_area_'+idTopic).innerHTML='<p>'+req.responseJS.sText+'</p>';
}
}
}
}
showWindowStatus('Обработка голосования...');
req.open(null, DIR_WEB_ROOT+'/include/ajax/questionVote.php', true);
req.send( { idTopic: idTopic, idAnswer: idAnswer } );
}
function ajaxVoteUser(idUser,value) {
var req = new JsHttpRequest();
@ -345,3 +366,29 @@ function showUserVote(vote,idUser) {
hideUserVoteAll(idUser);
document.getElementById(vote+'_'+idUser).style.display='inline';
}
// для опроса
function addField(btn){
tr = btn;
while (tr.tagName != 'TR') tr = tr.parentNode;
var newTr = tr.parentNode.insertBefore(tr.cloneNode(true),tr.nextSibling);
checkFieldForLast();
}
function checkFieldForLast(){
btns = document.getElementsByName('drop_answer');
for (i = 0; i < btns.length; i++){
btns[i].disabled = false;
}
if (btns.length<=2) {
btns[0].disabled = true;
btns[1].disabled = true;
}
}
function dropField(btn){
tr = btn;
while (tr.tagName != 'TR') tr = tr.parentNode;
tr.parentNode.removeChild(tr);
checkFieldForLast();
}

View file

@ -49,11 +49,11 @@
<TD class="subitem2 three_columns{if $sMenuItemSelect=='topic'} active_personal{/if}" noWrap align=middle>
<IMG class=arrow_cc height=7 src="{$DIR_STATIC_SKIN}/img/{if $sMenuItemSelect=='topic'}arrow_menu_main.gif{else}arrow_menu_main_un.gif{/if}" width=10><A href="{$DIR_WEB_ROOT}/topic/{$sMenuSubItemSelect}/">Топик</A>
</TD>
<!--
<TD class="subitem2 three_columns{if $sMenuItemSelect=='question'} active_personal{/if}" noWrap align=middle>
<IMG class=arrow_cc height=7 src="{$DIR_STATIC_SKIN}/img/{if $sMenuItemSelect=='question'}arrow_menu_main.gif{else}arrow_menu_main_un.gif{/if}" width=10><A href="{$DIR_WEB_ROOT}/question/{$sMenuSubItemSelect}/">Вопрос</A>
</TD>
-->
<TD class="subitem2 three_columns{if $sMenuItemSelect=='link'} active_personal{/if}" noWrap align=middle>
<IMG class=arrow_cc height=7 src="{$DIR_STATIC_SKIN}/img/{if $sMenuItemSelect=='link'}arrow_menu_main.gif{else}arrow_menu_main_un.gif{/if}" width=10><A href="{$DIR_WEB_ROOT}/link/{$sMenuSubItemSelect}/">Ссылка</A>
</TD>

View file

@ -15,7 +15,33 @@
{/if}
<a href="{$DIR_WEB_ROOT}/rss/comments/{$oTopic->getId()}/" title="RSS лента"><IMG height=12 src="{$DIR_STATIC_SKIN}/img/rss_small.gif" width=12></a>
</h1>
<div class="groups_topic_text">
<div class="groups_topic_text">
{if $oTopic->getType()=='question'}
<div class="poll" style="margin-top:20px;" id="topic_question_area_{$oTopic->getId()}">
{if !$oTopic->getUserQuestionIsVote()}
{foreach from=$oTopic->getQuestionAnswers() key=key item=aAnswer}
<input type="radio" name="topic_answer_{$oTopic->getId()}" value="{$key}" id="topic_answer_{$oTopic->getId()}_{$key}" onchange="document.getElementById('topic_answer_{$oTopic->getId()}_value').value=this.value;"> <label for="topic_answer_{$oTopic->getId()}_{$key}">{$aAnswer.text}</label> <br>
{/foreach}
<br>
<input type="hidden" id="topic_answer_{$oTopic->getId()}_value" value="77">
<input type="submit" value="голосовать" onclick="ajaxQuestionVote({$oTopic->getId()},document.getElementById('topic_answer_{$oTopic->getId()}_value').value)">
<input type="submit" value="воздержаться" onclick="ajaxQuestionVote({$oTopic->getId()},-1)">
<br><br>
<span class="total">Проголосовало: {$oTopic->getQuestionCountVote()}. Воздержалось: {$oTopic->getQuestionCountVoteAbstain()}</span><br>
{else}
{foreach from=$oTopic->getQuestionAnswers() key=key item=aAnswer}
<dl>
<dt><strong>{$oTopic->getQuestionAnswerPercent($key)}%</strong><br/>({$aAnswer.count})</dt>
<dd>{$aAnswer.text}<br/><img width="{$oTopic->getQuestionAnswerPercent($key)}%" height="5" alt="" src="{$DIR_STATIC_SKIN}/img/vote_space.gif"/></dd>
</dl>
{/foreach}
<span class="total">Проголосовало: {$oTopic->getQuestionCountVote()}. Воздержалось: {$oTopic->getQuestionCountVoteAbstain()}</span><br>
{/if}
</div>
<br>
{/if}
{$oTopic->getText()}
<div style="clear: left;"></div>
<div class="posttags">

View file

@ -18,6 +18,34 @@
{/if}
</h1>
<div class="groups_topic_text">
{if $oTopic->getType()=='question'}
<div class="poll" style="margin-top:20px;" id="topic_question_area_{$oTopic->getId()}">
{if !$oTopic->getUserQuestionIsVote()}
{foreach from=$oTopic->getQuestionAnswers() key=key item=aAnswer}
<input type="radio" name="topic_answer_{$oTopic->getId()}" value="{$key}" id="topic_answer_{$oTopic->getId()}_{$key}" onchange="document.getElementById('topic_answer_{$oTopic->getId()}_value').value=this.value;"> <label for="topic_answer_{$oTopic->getId()}_{$key}">{$aAnswer.text}</label> <br>
{/foreach}
<br>
<input type="hidden" id="topic_answer_{$oTopic->getId()}_value" value="77">
<input type="submit" value="голосовать" onclick="ajaxQuestionVote({$oTopic->getId()},document.getElementById('topic_answer_{$oTopic->getId()}_value').value)">
<input type="submit" value="воздержаться" onclick="ajaxQuestionVote({$oTopic->getId()},-1)">
<br><br>
<span class="total">Проголосовало: {$oTopic->getQuestionCountVote()}. Воздержалось: {$oTopic->getQuestionCountVoteAbstain()}</span><br>
{else}
{foreach from=$oTopic->getQuestionAnswers() key=key item=aAnswer}
<dl>
<dt><strong>{$oTopic->getQuestionAnswerPercent($key)}%</strong><br/>({$aAnswer.count})</dt>
<dd>{$aAnswer.text}<br/><img width="{$oTopic->getQuestionAnswerPercent($key)}%" height="5" alt="" src="{$DIR_STATIC_SKIN}/img/vote_space.gif"/></dd>
</dl>
{/foreach}
<span class="total">Проголосовало: {$oTopic->getQuestionCountVote()}. Воздержалось: {$oTopic->getQuestionCountVoteAbstain()}</span><br>
{/if}
</div>
<br>
{/if}
{$oTopic->getTextShort()}
{if $oTopic->getTextShort()!=$oTopic->getText()}
<br><br>( <a href="{$oTopic->getUrl()}" title="Прочитать топик полностью">Читать дальше</a> )