mirror of
https://github.com/Oreolek/ifhub.club.git
synced 2024-06-16 23:00:51 +03:00
Merge branch 'master' of https://github.com/livestreet/livestreet
Conflicts: application/classes/actions/ActionAjax.class.php application/frontend/i18n/ru.php
This commit is contained in:
commit
19765231c9
|
@ -50,7 +50,6 @@ class ActionAjax extends Action {
|
|||
$this->AddEventPreg('/^vote$/i','/^topic$/','EventVoteTopic');
|
||||
$this->AddEventPreg('/^vote$/i','/^blog$/','EventVoteBlog');
|
||||
$this->AddEventPreg('/^vote$/i','/^user$/','EventVoteUser');
|
||||
$this->AddEventPreg('/^vote$/i','/^question$/','EventVoteQuestion');
|
||||
$this->AddEventPreg('/^vote$/i','/^get$/','/^info$/','/^topic$/','EventVoteGetInfoTopic');
|
||||
|
||||
$this->AddEventPreg('/^favourite$/i','/^save-tags/','EventFavouriteSaveTags');
|
||||
|
@ -90,6 +89,13 @@ class ActionAjax extends Action {
|
|||
$this->AddEventPreg('/^property$/i','/^tags$/','/^autocompleter$/','/^$/','EventPropertyTagsAutocompleter');
|
||||
|
||||
$this->AddEventPreg('/^validate$/i','/^captcha$/','/^$/','EventValidateCaptcha');
|
||||
|
||||
$this->AddEventPreg('/^poll$/i','/^modal-create$/','/^$/','EventPollModalCreate');
|
||||
$this->AddEventPreg('/^poll$/i','/^modal-update/','/^$/','EventPollModalUpdate');
|
||||
$this->AddEventPreg('/^poll$/i','/^create$/','/^$/','EventPollCreate');
|
||||
$this->AddEventPreg('/^poll$/i','/^update$/','/^$/','EventPollUpdate');
|
||||
$this->AddEventPreg('/^poll$/i','/^remove$/','/^$/','EventPollRemove');
|
||||
$this->AddEventPreg('/^poll$/i','/^vote$/','/^$/','EventPollVote');
|
||||
|
||||
$this->AddEvent('modal-friend-list', 'EventModalFriendList');
|
||||
}
|
||||
|
@ -128,6 +134,248 @@ class ActionAjax extends Action {
|
|||
$this->Viewer_AssignAjax('sText', $oViewer->Fetch("modals/modal.user_list.tpl"));
|
||||
}
|
||||
|
||||
|
||||
protected function EventPollVote() {
|
||||
if (!$this->oUserCurrent) {
|
||||
return $this->EventErrorDebug();
|
||||
}
|
||||
|
||||
if (!$oPoll=$this->Poll_GetPollById(getRequestStr('id'))) {
|
||||
return $this->EventErrorDebug();
|
||||
}
|
||||
|
||||
/**
|
||||
* Истекло время голосования?
|
||||
*/
|
||||
if (!$oPoll->isAllowVote()) {
|
||||
$this->Message_AddErrorSingle('В этом опросе уже нельзя голосовать');
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Пользователь уже голосовал?
|
||||
*/
|
||||
if ($this->Poll_GetVoteByUserIdAndPollId($this->oUserCurrent->getId(),$oPoll->getId())) {
|
||||
$this->Message_AddErrorSingle('Вы уже голосовали');
|
||||
return;
|
||||
}
|
||||
|
||||
$aAnswerIds=array();
|
||||
$aAnswerItems=array();
|
||||
if (!getRequest('abstain')) {
|
||||
/**
|
||||
* Проверяем варианты ответов
|
||||
*/
|
||||
if (!$aAnswer=(array)getRequest('answers')) {
|
||||
$this->Message_AddErrorSingle('Необходимо выбрать вариант');
|
||||
return;
|
||||
}
|
||||
|
||||
foreach($aAnswer as $iAnswerId) {
|
||||
if (!is_numeric($iAnswerId)) {
|
||||
return $this->EventErrorDebug();
|
||||
}
|
||||
$aAnswerIds[]=$iAnswerId;
|
||||
}
|
||||
/**
|
||||
* Корректность ID вариантов
|
||||
*/
|
||||
$aAnswerItems=$this->Poll_GetAnswerItemsByFilter(array('id in'=>$aAnswerIds,'poll_id'=>$oPoll->getId()));
|
||||
if (count($aAnswerItems)!=count($aAnswerIds)) {
|
||||
return $this->EventErrorDebug();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Голосуем
|
||||
*/
|
||||
$oVote=Engine::GetEntity('ModulePoll_EntityVote');
|
||||
$oVote->setPollId($oPoll->getId());
|
||||
$oVote->setPoll($oPoll); // для быстродействия/оптимизации
|
||||
$oVote->setUserId($this->oUserCurrent->getId());
|
||||
$oVote->setAnswers($aAnswerIds);
|
||||
$oVote->setAnswersObject($aAnswerItems); // передаем для быстродействия, чтобы не запрашивать варианты еще раз после сохранения голоса
|
||||
if ($oVote->Add()) {
|
||||
$oViewer=$this->Viewer_GetLocalViewer();
|
||||
$oViewer->Assign('oPoll',$oPoll);
|
||||
$this->Viewer_AssignAjax('sText',$oViewer->Fetch("polls/poll.result.tpl"));
|
||||
} else {
|
||||
return $this->EventErrorDebug();
|
||||
}
|
||||
}
|
||||
|
||||
protected function EventPollCreate() {
|
||||
if (!$this->oUserCurrent) {
|
||||
return $this->EventErrorDebug();
|
||||
}
|
||||
/**
|
||||
* Создаем
|
||||
*/
|
||||
$oPoll=Engine::GetEntity('ModulePoll_EntityPoll');
|
||||
$oPoll->_setValidateScenario('create');
|
||||
$oPoll->_setDataSafe(getRequest('poll'));
|
||||
$oPoll->setAnswersRaw(getRequest('answers'));
|
||||
$oPoll->setTargetRaw(getRequest('target'));
|
||||
$oPoll->setUserId($this->oUserCurrent->getId());
|
||||
|
||||
if ($oPoll->_Validate()) {
|
||||
if ($oPoll->Add()) {
|
||||
$oViewer=$this->Viewer_GetLocalViewer();
|
||||
$oViewer->Assign('oPoll',$oPoll);
|
||||
$this->Viewer_AssignAjax('sPollItem',$oViewer->Fetch("polls/poll.form.item.tpl"));
|
||||
return true;
|
||||
} else {
|
||||
$this->Message_AddError($this->Lang_Get('common.error.save'),$this->Lang_Get('error'));
|
||||
}
|
||||
} else {
|
||||
$this->Message_AddError($oPoll->_getValidateError(),$this->Lang_Get('error'));
|
||||
}
|
||||
}
|
||||
|
||||
protected function EventPollUpdate() {
|
||||
if (!$this->oUserCurrent) {
|
||||
return $this->EventErrorDebug();
|
||||
}
|
||||
|
||||
if (!$oPoll=$this->Poll_GetPollById(getRequestStr('poll_id'))) {
|
||||
return $this->EventErrorDebug();
|
||||
}
|
||||
|
||||
/**
|
||||
* Проверяем корректность target'а
|
||||
*/
|
||||
if ($oPoll->getTargetId()) {
|
||||
if (!$this->Poll_CheckTarget($oPoll->getTargetType(),$oPoll->getTargetId())) {
|
||||
return $this->EventErrorDebug();
|
||||
}
|
||||
} else {
|
||||
$sTarget=isset($_REQUEST['target']['tmp']) ? $_REQUEST['target']['tmp'] : '';
|
||||
if (!$this->Poll_IsAllowTargetType($oPoll->getTargetType()) or $oPoll->getTargetTmp()!=$sTarget) {
|
||||
return $this->EventErrorDebug();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Обновляем
|
||||
*/
|
||||
$oPoll->_setValidateScenario('update');
|
||||
$oPoll->_setDataSafe(getRequest('poll'));
|
||||
$oPoll->setAnswersRaw(getRequest('answers'));
|
||||
|
||||
if ($oPoll->_Validate()) {
|
||||
if ($oPoll->Update()) {
|
||||
$oViewer=$this->Viewer_GetLocalViewer();
|
||||
$oViewer->Assign('oPoll',$oPoll);
|
||||
$this->Viewer_AssignAjax('sPollItem',$oViewer->Fetch("polls/poll.form.item.tpl"));
|
||||
$this->Viewer_AssignAjax('iPollId',$oPoll->getId());
|
||||
return true;
|
||||
} else {
|
||||
$this->Message_AddError($this->Lang_Get('common.error.save'),$this->Lang_Get('error'));
|
||||
}
|
||||
} else {
|
||||
$this->Message_AddError($oPoll->_getValidateError(),$this->Lang_Get('error'));
|
||||
}
|
||||
}
|
||||
|
||||
protected function EventPollRemove() {
|
||||
if (!$this->oUserCurrent) {
|
||||
return $this->EventErrorDebug();
|
||||
}
|
||||
|
||||
if (!$oPoll=$this->Poll_GetPollById(getRequestStr('id'))) {
|
||||
return $this->EventErrorDebug();
|
||||
}
|
||||
|
||||
/**
|
||||
* Проверяем корректность target'а
|
||||
*/
|
||||
if ($oPoll->getTargetId()) {
|
||||
if (!$this->Poll_CheckTarget($oPoll->getTargetType(),$oPoll->getTargetId())) {
|
||||
return $this->EventErrorDebug();
|
||||
}
|
||||
} else {
|
||||
if (!$this->Poll_IsAllowTargetType($oPoll->getTargetType()) or $oPoll->getTargetTmp()!=getRequestStr('tmp')) {
|
||||
return $this->EventErrorDebug();
|
||||
}
|
||||
}
|
||||
|
||||
if (!$oPoll->isAllowRemove()) {
|
||||
$this->Message_AddError('Этот опрос уже нельзя удалить');
|
||||
}
|
||||
|
||||
/**
|
||||
* Удаляем
|
||||
*/
|
||||
if ($oPoll->Delete()) {
|
||||
return true;
|
||||
} else {
|
||||
$this->Message_AddError($this->Lang_Get('common.error.save'),$this->Lang_Get('error'));
|
||||
}
|
||||
}
|
||||
|
||||
protected function EventPollModalCreate() {
|
||||
if (!$this->oUserCurrent) {
|
||||
return $this->EventErrorDebug();
|
||||
}
|
||||
|
||||
/**
|
||||
* Проверяем корректность target'а
|
||||
*/
|
||||
$sTargetType=getRequestStr('target_type');
|
||||
$sTargetId=getRequestStr('target_id');
|
||||
|
||||
$sTargetTmp=empty($_COOKIE['poll_target_tmp_'.$sTargetType]) ? getRequestStr('target_tmp') : $_COOKIE['poll_target_tmp_'.$sTargetType];
|
||||
if ($sTargetId) {
|
||||
$sTargetTmp=null;
|
||||
if (!$this->Poll_CheckTarget($sTargetType,$sTargetId)) {
|
||||
return $this->EventErrorDebug();
|
||||
}
|
||||
} else {
|
||||
$sTargetId=null;
|
||||
if (!$this->Poll_IsAllowTargetType($sTargetType)) {
|
||||
return $this->EventErrorDebug();
|
||||
}
|
||||
if (!$sTargetTmp) {
|
||||
$sTargetTmp=func_generator();
|
||||
setcookie('poll_target_tmp_'.$sTargetType,$sTargetTmp, time()+24*3600,Config::Get('sys.cookie.path'),Config::Get('sys.cookie.host'));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
$oViewer=$this->Viewer_GetLocalViewer();
|
||||
$oViewer->Assign('sTargetType',$sTargetType);
|
||||
$oViewer->Assign('sTargetId',$sTargetId);
|
||||
$oViewer->Assign('sTargetTmp',$sTargetTmp);
|
||||
$this->Viewer_AssignAjax('sText',$oViewer->Fetch("modals/modal.poll_create.tpl"));
|
||||
}
|
||||
|
||||
protected function EventPollModalUpdate() {
|
||||
if (!$this->oUserCurrent) {
|
||||
return $this->EventErrorDebug();
|
||||
}
|
||||
|
||||
if (!$oPoll=$this->Poll_GetPollById(getRequestStr('id'))) {
|
||||
return $this->EventErrorDebug();
|
||||
}
|
||||
|
||||
/**
|
||||
* Проверяем корректность target'а
|
||||
*/
|
||||
if ($oPoll->getTargetId()) {
|
||||
if (!$this->Poll_CheckTarget($oPoll->getTargetType(),$oPoll->getTargetId())) {
|
||||
return $this->EventErrorDebug();
|
||||
}
|
||||
} else {
|
||||
if (!$this->Poll_IsAllowTargetType($oPoll->getTargetType()) or $oPoll->getTargetTmp()!=getRequestStr('target_tmp')) {
|
||||
return $this->EventErrorDebug();
|
||||
}
|
||||
}
|
||||
|
||||
$oViewer=$this->Viewer_GetLocalViewer();
|
||||
$oViewer->Assign('oPoll',$oPoll);
|
||||
$oViewer->Assign('sTargetTmp',getRequestStr('target_tmp'));
|
||||
$this->Viewer_AssignAjax('sText',$oViewer->Fetch("modals/modal.poll_create.tpl"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajax валидация каптчи
|
||||
*/
|
||||
|
@ -839,73 +1087,6 @@ class ActionAjax extends Action {
|
|||
return;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Голосование за вариант ответа в опросе
|
||||
*
|
||||
*/
|
||||
protected function EventVoteQuestion() {
|
||||
/**
|
||||
* Пользователь авторизован?
|
||||
*/
|
||||
if (!$this->oUserCurrent) {
|
||||
$this->Message_AddErrorSingle($this->Lang_Get('need_authorization'),$this->Lang_Get('error'));
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Параметры голосования
|
||||
*/
|
||||
$idAnswer=getRequestStr('idAnswer',null,'post');
|
||||
$idTopic=getRequestStr('idTopic',null,'post');
|
||||
/**
|
||||
* Топик существует?
|
||||
*/
|
||||
if (!($oTopic=$this->Topic_GetTopicById($idTopic))) {
|
||||
return $this->EventErrorDebug();
|
||||
}
|
||||
/**
|
||||
* Тип топика - опрос?
|
||||
*/
|
||||
if ($oTopic->getType()!='question') {
|
||||
return $this->EventErrorDebug();
|
||||
}
|
||||
/**
|
||||
* Уже голосовал?
|
||||
*/
|
||||
if ($oTopicQuestionVote=$this->Topic_GetTopicQuestionVote($oTopic->getId(),$this->oUserCurrent->getId())) {
|
||||
$this->Message_AddErrorSingle($this->Lang_Get('topic_question_vote_already'),$this->Lang_Get('error'));
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Вариант ответа
|
||||
*/
|
||||
$aAnswer=$oTopic->getQuestionAnswers();
|
||||
if (!isset($aAnswer[$idAnswer]) and $idAnswer!=-1) {
|
||||
return $this->EventErrorDebug();
|
||||
}
|
||||
|
||||
if ($idAnswer==-1) {
|
||||
$oTopic->setQuestionCountVoteAbstain($oTopic->getQuestionCountVoteAbstain()+1);
|
||||
} else {
|
||||
$oTopic->increaseQuestionAnswerVote($idAnswer);
|
||||
}
|
||||
$oTopic->setQuestionCountVote($oTopic->getQuestionCountVote()+1);
|
||||
/**
|
||||
* Голосуем(отвечаем на опрос)
|
||||
*/
|
||||
$oTopicQuestionVote=Engine::GetEntity('Topic_TopicQuestionVote');
|
||||
$oTopicQuestionVote->setTopicId($oTopic->getId());
|
||||
$oTopicQuestionVote->setVoterId($this->oUserCurrent->getId());
|
||||
$oTopicQuestionVote->setAnswer($idAnswer);
|
||||
|
||||
if ($this->Topic_AddTopicQuestionVote($oTopicQuestionVote) and $this->Topic_updateTopic($oTopic)) {
|
||||
$this->Message_AddNoticeSingle($this->Lang_Get('topic_question_vote_ok'),$this->Lang_Get('attention'));
|
||||
$oViewer=$this->Viewer_GetLocalViewer();
|
||||
$oViewer->Assign('oTopic',$oTopic);
|
||||
$this->Viewer_AssignAjax('sText',$oViewer->Fetch("topics/poll_result.tpl"));
|
||||
} else {
|
||||
return $this->EventErrorDebug();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Сохраняет теги для избранного
|
||||
*
|
||||
|
|
|
@ -159,7 +159,7 @@ class ActionContent extends Action {
|
|||
/**
|
||||
* Проверяем тип топика
|
||||
*/
|
||||
if (!$this->Topic_IsAllowTopicType($oTopic->getType())) {
|
||||
if (!$oTopicType=$this->Topic_GetTopicType($oTopic->getType())) {
|
||||
return parent::EventNotFound();
|
||||
}
|
||||
/**
|
||||
|
@ -176,7 +176,7 @@ class ActionContent extends Action {
|
|||
* Загружаем переменные в шаблон
|
||||
*/
|
||||
$this->Viewer_Assign('aBlogsAllow',$this->Blog_GetBlogsAllowByUser($this->oUserCurrent));
|
||||
$this->Viewer_Assign('sTopicType',$oTopic->getType());
|
||||
$this->Viewer_Assign('oTopicType',$oTopicType);
|
||||
$this->Viewer_AddHtmlTitle($this->Lang_Get('topic_topic_edit'));
|
||||
|
||||
$this->Viewer_Assign('oTopicEdit', $oTopic);
|
||||
|
@ -189,7 +189,7 @@ class ActionContent extends Action {
|
|||
*/
|
||||
protected function EventAdd() {
|
||||
$sTopicType=$this->GetParam(0);
|
||||
if (!$this->Topic_IsAllowTopicType($sTopicType)) {
|
||||
if (!$oTopicType=$this->Topic_GetTopicType($sTopicType)) {
|
||||
return parent::EventNotFound();
|
||||
}
|
||||
$this->sMenuSubItemSelect=$sTopicType;
|
||||
|
@ -200,7 +200,7 @@ class ActionContent extends Action {
|
|||
/**
|
||||
* Загружаем переменные в шаблон
|
||||
*/
|
||||
$this->Viewer_Assign('sTopicType',$sTopicType);
|
||||
$this->Viewer_Assign('oTopicType',$oTopicType);
|
||||
$this->Viewer_Assign('aBlogsAllow',$this->Blog_GetBlogsAllowByUser($this->oUserCurrent));
|
||||
$this->Viewer_AddHtmlTitle($this->Lang_Get('topic_topic_create'));
|
||||
$this->SetTemplateAction('add');
|
||||
|
@ -211,12 +211,10 @@ class ActionContent extends Action {
|
|||
|
||||
$aTopicRequest=getRequest('topic');
|
||||
if (!(isset($aTopicRequest['id']) and $oTopic=$this->Topic_GetTopicById($aTopicRequest['id']))) {
|
||||
$this->Message_AddErrorSingle($this->Lang_Get('system_error'));
|
||||
return;
|
||||
return $this->EventErrorDebug();
|
||||
}
|
||||
if (!$this->Topic_IsAllowTopicType($oTopic->getType())) {
|
||||
$this->Message_AddErrorSingle($this->Lang_Get('system_error'));
|
||||
return;
|
||||
return $this->EventErrorDebug();
|
||||
}
|
||||
/**
|
||||
* Проверяем разрешено ли постить топик по времени
|
||||
|
@ -230,8 +228,7 @@ class ActionContent extends Action {
|
|||
* Если права на редактирование
|
||||
*/
|
||||
if (!$this->ACL_IsAllowEditTopic($oTopic,$this->oUserCurrent)) {
|
||||
$this->Message_AddErrorSingle($this->Lang_Get('system_error'));
|
||||
return;
|
||||
return $this->EventErrorDebug();
|
||||
}
|
||||
/**
|
||||
* Сохраняем старое значение идентификатора блога
|
||||
|
@ -341,9 +338,8 @@ class ActionContent extends Action {
|
|||
* TODO: Здесь нужна проверка прав на создание топика
|
||||
*/
|
||||
$sTopicType=getRequestStr('topic_type');
|
||||
if (!$this->Topic_IsAllowTopicType($sTopicType)) {
|
||||
$this->Message_AddErrorSingle($this->Lang_Get('system_error'));
|
||||
return;
|
||||
if (!$oTopicType=$this->Topic_GetTopicType($sTopicType)) {
|
||||
return $this->EventErrorDebug();
|
||||
}
|
||||
/**
|
||||
* Проверяем разрешено ли постить топик по времени
|
||||
|
@ -421,6 +417,12 @@ class ActionContent extends Action {
|
|||
* Фиксируем ID у media файлов топика
|
||||
*/
|
||||
$this->Media_ReplaceTargetTmpById('topic',$oTopic->getId());
|
||||
/**
|
||||
* Фиксируем ID у опросов
|
||||
*/
|
||||
if ($oTopicType->getParam('allow_poll')) {
|
||||
$this->Poll_ReplaceTargetTmpById('topic',$oTopic->getId());
|
||||
}
|
||||
/**
|
||||
* Добавляем автора топика в подписчики на новые комментарии к этому топику
|
||||
*/
|
||||
|
|
51
application/classes/blocks/BlockPollFormItems.class.php
Normal file
51
application/classes/blocks/BlockPollFormItems.class.php
Normal file
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
/*-------------------------------------------------------
|
||||
*
|
||||
* LiveStreet Engine Social Networking
|
||||
* Copyright © 2008 Mzhelskiy Maxim
|
||||
*
|
||||
*--------------------------------------------------------
|
||||
*
|
||||
* Official site: www.livestreet.ru
|
||||
* Contact e-mail: rus.engine@gmail.com
|
||||
*
|
||||
* GNU General Public License, version 2:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
*
|
||||
---------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Используется для вывода списка опросов в форме редактирования объекта
|
||||
*
|
||||
* @package blocks
|
||||
* @since 1.0
|
||||
*/
|
||||
class BlockPollFormItems extends Block {
|
||||
/**
|
||||
* Запуск обработки
|
||||
*/
|
||||
public function Exec() {
|
||||
$sTargetType=$this->GetParam('target_type');
|
||||
$sTargetId=$this->GetParam('target_id');
|
||||
$sTargetTmp=empty($_COOKIE['poll_target_tmp_'.$sTargetType]) ? $this->GetParam('target_tmp') : $_COOKIE['poll_target_tmp_'.$sTargetType];
|
||||
|
||||
$aFilter=array('target_type'=>$sTargetType,'#order'=>array('id'=>'asc'));
|
||||
if ($sTargetId) {
|
||||
$sTargetTmp=null;
|
||||
if (!$this->Poll_CheckTarget($sTargetType,$sTargetId)) {
|
||||
return false;
|
||||
}
|
||||
$aFilter['target_id']=$sTargetId;
|
||||
} else {
|
||||
$sTargetId=null;
|
||||
if (!$sTargetTmp or !$this->Poll_IsAllowTargetType($sTargetType)) {
|
||||
return false;
|
||||
}
|
||||
$aFilter['target_tmp']=$sTargetTmp;
|
||||
}
|
||||
$aPollItems=$this->Poll_GetPollItemsByFilter($aFilter);
|
||||
|
||||
$this->Viewer_Assign('aPollItems',$aPollItems);
|
||||
}
|
||||
}
|
172
application/classes/modules/poll/Poll.class.php
Normal file
172
application/classes/modules/poll/Poll.class.php
Normal file
|
@ -0,0 +1,172 @@
|
|||
<?php
|
||||
/**
|
||||
* LiveStreet CMS
|
||||
* Copyright © 2013 OOO "ЛС-СОФТ"
|
||||
*
|
||||
* ------------------------------------------------------
|
||||
*
|
||||
* Official site: www.livestreetcms.com
|
||||
* Contact e-mail: office@livestreetcms.com
|
||||
*
|
||||
* GNU General Public License, version 2:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
*
|
||||
* ------------------------------------------------------
|
||||
*
|
||||
* @link http://www.livestreetcms.com
|
||||
* @copyright 2013 OOO "ЛС-СОФТ"
|
||||
* @author Maxim Mzhelskiy <rus.engine@gmail.com>
|
||||
*
|
||||
*/
|
||||
|
||||
class ModulePoll extends ModuleORM {
|
||||
|
||||
/**
|
||||
* Объект текущего пользователя
|
||||
*
|
||||
* @var ModuleUser_EntityUser|null
|
||||
*/
|
||||
protected $oUserCurrent;
|
||||
|
||||
protected $aTargetTypes=array(
|
||||
'topic'=>array(),
|
||||
);
|
||||
|
||||
/**
|
||||
* Инициализация
|
||||
*
|
||||
*/
|
||||
public function Init() {
|
||||
parent::Init();
|
||||
$this->oUserCurrent=$this->User_GetUserCurrent();
|
||||
}
|
||||
/**
|
||||
* Возвращает список типов объектов
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function GetTargetTypes() {
|
||||
return $this->aTargetTypes;
|
||||
}
|
||||
/**
|
||||
* Добавляет в разрешенные новый тип
|
||||
*
|
||||
* @param string $sTargetType Тип
|
||||
* @param array $aParams Параметры
|
||||
* @return bool
|
||||
*/
|
||||
public function AddTargetType($sTargetType,$aParams=array()) {
|
||||
if (!array_key_exists($sTargetType,$this->aTargetTypes)) {
|
||||
$this->aTargetTypes[$sTargetType]=$aParams;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Проверяет разрешен ли данный тип
|
||||
*
|
||||
* @param string $sTargetType Тип
|
||||
* @return bool
|
||||
*/
|
||||
public function IsAllowTargetType($sTargetType) {
|
||||
return in_array($sTargetType,array_keys($this->aTargetTypes));
|
||||
}
|
||||
/**
|
||||
* Возвращает парметры нужного типа
|
||||
*
|
||||
* @param string $sTargetType
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function GetTargetTypeParams($sTargetType) {
|
||||
if ($this->IsAllowTargetType($sTargetType)) {
|
||||
return $this->aTargetTypes[$sTargetType];
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Проверка объекта target - владелец медиа
|
||||
*
|
||||
* @param string $sTargetType Тип
|
||||
* @param int $iTargetId ID владельца
|
||||
* @return bool
|
||||
*/
|
||||
public function CheckTarget($sTargetType,$iTargetId) {
|
||||
if (!$this->IsAllowTargetType($sTargetType)) {
|
||||
return false;
|
||||
}
|
||||
$sMethod = 'CheckTarget'.func_camelize($sTargetType);
|
||||
if (method_exists($this,$sMethod)) {
|
||||
return $this->$sMethod($iTargetId);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Заменяет временный идентификатор на необходимый ID объекта
|
||||
*
|
||||
* @param string $sTargetType
|
||||
* @param string $sTargetId
|
||||
* @param null|string $sTargetTmp Если не задан, то берется их куки "poll_target_tmp_{$sTargetType}"
|
||||
*/
|
||||
public function ReplaceTargetTmpById($sTargetType,$sTargetId,$sTargetTmp=null) {
|
||||
$sCookieKey='poll_target_tmp_'.$sTargetType;
|
||||
if (is_null($sTargetTmp) and isset($_COOKIE[$sCookieKey])) {
|
||||
$sTargetTmp=$_COOKIE[$sCookieKey];
|
||||
setcookie($sCookieKey,null,-1,Config::Get('sys.cookie.path'),Config::Get('sys.cookie.host'));
|
||||
}
|
||||
if (is_string($sTargetTmp)) {
|
||||
$aPollItems=$this->Poll_GetPollItemsByTargetTmpAndTargetType($sTargetTmp,$sTargetType);
|
||||
foreach($aPollItems as $oPoll) {
|
||||
$oPoll->setTargetTmp(null);
|
||||
$oPoll->setTargetId($sTargetId);
|
||||
$oPoll->Update();
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Возвращает список опросов для объекта
|
||||
*
|
||||
* @param string $sTargetType
|
||||
* @param string $sTargetId
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function GetPollItemsByTarget($sTargetType,$sTargetId) {
|
||||
$aFilter=array(
|
||||
'target_type'=>$sTargetType,
|
||||
'target_id'=>$sTargetId,
|
||||
'#with'=>array('answers')
|
||||
);
|
||||
if ($this->oUserCurrent) {
|
||||
$aFilter['#with']['vote_current']=array('user_id'=>$this->oUserCurrent->getId(),'#value-default'=>false);
|
||||
} else {
|
||||
$aFilter['#with']['vote_current']=array('#value-set'=>false);
|
||||
}
|
||||
$aPollItems=$this->Poll_GetPollItemsByFilter($aFilter);
|
||||
return $aPollItems;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Проверка владельца с типом "topic"
|
||||
* Название метода формируется автоматически
|
||||
*
|
||||
* @param int $iTargetId ID владельца
|
||||
* @return bool
|
||||
*/
|
||||
public function CheckTargetTopic($iTargetId) {
|
||||
if ($oTopic=$this->Topic_GetTopicById($iTargetId)) {
|
||||
if (!$oTopicType=$this->Topic_GetTopicType($oTopic->getType()) or !$oTopicType->getParam('allow_poll')) {
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Проверяем права на редактирование топика
|
||||
*/
|
||||
if ($this->ACL_IsAllowEditTopic($oTopic,$this->oUserCurrent)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
<?php
|
||||
/**
|
||||
* LiveStreet CMS
|
||||
* Copyright © 2013 OOO "ЛС-СОФТ"
|
||||
*
|
||||
* ------------------------------------------------------
|
||||
*
|
||||
* Official site: www.livestreetcms.com
|
||||
* Contact e-mail: office@livestreetcms.com
|
||||
*
|
||||
* GNU General Public License, version 2:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
*
|
||||
* ------------------------------------------------------
|
||||
*
|
||||
* @link http://www.livestreetcms.com
|
||||
* @copyright 2013 OOO "ЛС-СОФТ"
|
||||
* @author Maxim Mzhelskiy <rus.engine@gmail.com>
|
||||
*
|
||||
*/
|
||||
|
||||
class ModulePoll_EntityAnswer extends EntityORM {
|
||||
|
||||
protected $aValidateRules=array(
|
||||
array('title','string','allowEmpty'=>false,'min'=>1,'max'=>250),
|
||||
array('title','check_title'),
|
||||
);
|
||||
|
||||
protected $aRelations=array(
|
||||
'poll' => array(self::RELATION_TYPE_BELONGS_TO,'ModulePoll_EntityPoll','poll_id'),
|
||||
);
|
||||
|
||||
protected function beforeSave() {
|
||||
if ($this->_isNew()) {
|
||||
$this->setDateCreate(date("Y-m-d H:i:s"));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function afterDelete() {
|
||||
/**
|
||||
* Удаляем голосования
|
||||
*/
|
||||
$aVoteItems=$this->Poll_GetVoteItemsByAnswerId($this->getId());
|
||||
foreach($aVoteItems as $oVote) {
|
||||
$oVote->Delete();
|
||||
}
|
||||
}
|
||||
|
||||
public function ValidateCheckTitle() {
|
||||
$this->setTitle(htmlspecialchars($this->getTitle()));
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
237
application/classes/modules/poll/entity/Poll.entity.class.php
Normal file
237
application/classes/modules/poll/entity/Poll.entity.class.php
Normal file
|
@ -0,0 +1,237 @@
|
|||
<?php
|
||||
/**
|
||||
* LiveStreet CMS
|
||||
* Copyright © 2013 OOO "ЛС-СОФТ"
|
||||
*
|
||||
* ------------------------------------------------------
|
||||
*
|
||||
* Official site: www.livestreetcms.com
|
||||
* Contact e-mail: office@livestreetcms.com
|
||||
*
|
||||
* GNU General Public License, version 2:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
*
|
||||
* ------------------------------------------------------
|
||||
*
|
||||
* @link http://www.livestreetcms.com
|
||||
* @copyright 2013 OOO "ЛС-СОФТ"
|
||||
* @author Maxim Mzhelskiy <rus.engine@gmail.com>
|
||||
*
|
||||
*/
|
||||
|
||||
class ModulePoll_EntityPoll extends EntityORM {
|
||||
|
||||
protected $aValidateRules=array(
|
||||
array('title','string','allowEmpty'=>false,'min'=>3,'max'=>250,'on'=>array('create','update')),
|
||||
array('count_answer_max','number','allowEmpty'=>true,'integerOnly'=>true,'min'=>0,'on'=>array('create','update')),
|
||||
array('type','check_type','on'=>array('create','update')),
|
||||
array('answers_raw','check_answers_raw','on'=>array('create','update')),
|
||||
array('target_raw','check_target_raw','on'=>array('create')),
|
||||
array('title','check_title','on'=>array('create','update')),
|
||||
);
|
||||
|
||||
protected $aRelations=array(
|
||||
'answers' => array(self::RELATION_TYPE_HAS_MANY,'ModulePoll_EntityAnswer','poll_id'),
|
||||
'vote_current' => array(self::RELATION_TYPE_HAS_ONE,'ModulePoll_EntityVote','poll_id'),
|
||||
);
|
||||
|
||||
protected function beforeSave() {
|
||||
if ($this->_isNew()) {
|
||||
$this->setDateCreate(date("Y-m-d H:i:s"));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function afterSave() {
|
||||
/**
|
||||
* Сохраняем варианты
|
||||
*/
|
||||
if ($aAnswers=$this->getAnswersObject()) {
|
||||
foreach($aAnswers as $oAnswer) {
|
||||
$oAnswer->setPollId($this->getId());
|
||||
$oAnswer->Save();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Удаляем варианты
|
||||
*/
|
||||
if ($aAnswers=$this->getAnswersObjectForRemove()) {
|
||||
foreach($aAnswers as $oAnswer) {
|
||||
$oAnswer->Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function afterDelete() {
|
||||
/**
|
||||
* Удаляем варианты ответов
|
||||
*/
|
||||
$aAnswerItems=$this->Poll_GetAnswerItemsByPollId($this->getId());
|
||||
foreach($aAnswerItems as $oAnswer) {
|
||||
$oAnswer->Delete();
|
||||
}
|
||||
}
|
||||
|
||||
public function ValidateCheckTitle() {
|
||||
$this->setTitle(htmlspecialchars($this->getTitle()));
|
||||
return true;
|
||||
}
|
||||
|
||||
public function ValidateCheckType() {
|
||||
if (!$this->_isNew() and $this->getCountVote()) {
|
||||
/**
|
||||
* Запрещаем смену типа
|
||||
*/
|
||||
$this->setCountAnswerMax($this->_getOriginalDataOne('count_answer_max'));
|
||||
return true;
|
||||
}
|
||||
$iCount=$this->getCountAnswerMax();
|
||||
if ($this->getType()=='one') {
|
||||
$this->setCountAnswerMax(1);
|
||||
return true;
|
||||
} else {
|
||||
if ($iCount<2) {
|
||||
return 'Максимальное количество вариантов ответа должно быть больше одного';
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function ValidateCheckAnswersRaw() {
|
||||
if (!$this->_isNew() and !$this->isAllowUpdate()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$aAnswersRaw=$this->getAnswersRaw();
|
||||
if (!is_array($aAnswersRaw)) {
|
||||
return 'Необходимо заполнить варианты ответов';
|
||||
}
|
||||
if (count($aAnswersRaw)<2) {
|
||||
return 'Необходимо заполнить больше одного варианта ответов';
|
||||
}
|
||||
/**
|
||||
* Здесь может быть два варианта - создание опроса или редактирование, при редактирование могут передаваться ID ответов
|
||||
*/
|
||||
if (!$this->_isNew()) {
|
||||
$aAnswersOld=$this->Poll_GetAnswerItemsByFilter(array('poll_id'=>$this->getId(),'#index-from-primary'));
|
||||
} else {
|
||||
$aAnswersOld=array();
|
||||
}
|
||||
$aAnswers=array();
|
||||
foreach($aAnswersRaw as $aAnswer) {
|
||||
if ($this->_isNew() or !(isset($aAnswer['id']) and isset($aAnswersOld[$aAnswer['id']]) and $oAnswer=$aAnswersOld[$aAnswer['id']])) {
|
||||
$oAnswer=Engine::GetEntity('ModulePoll_EntityAnswer');
|
||||
}
|
||||
if ($oAnswer->getId()) {
|
||||
/**
|
||||
* Фильтруем список старых ответов для будущего удаления оставшихся
|
||||
*/
|
||||
unset($aAnswersOld[$oAnswer->getId()]);
|
||||
}
|
||||
$oAnswer->setTitle(isset($aAnswer['title']) ? $aAnswer['title'] : '');
|
||||
if (!$oAnswer->_Validate()) {
|
||||
return $oAnswer->_getValidateError();
|
||||
}
|
||||
$aAnswers[]=$oAnswer;
|
||||
}
|
||||
$this->setAnswersObject($aAnswers);
|
||||
|
||||
foreach($aAnswersOld as $oAnswer) {
|
||||
if ($oAnswer->getCountVote()) {
|
||||
return 'Нельзя удалить вариант ответа, за который уже голосовали';
|
||||
}
|
||||
}
|
||||
|
||||
$this->setAnswersObjectForRemove($aAnswersOld);
|
||||
return true;
|
||||
}
|
||||
|
||||
public function ValidateCheckTargetRaw() {
|
||||
$aTarget=$this->getTargetRaw();
|
||||
|
||||
$sTargetType=isset($aTarget['type']) ? $aTarget['type'] : '';
|
||||
$sTargetId=isset($aTarget['id']) ? $aTarget['id'] : '';
|
||||
$sTargetTmp=isset($aTarget['tmp']) ? $aTarget['tmp'] : '';
|
||||
|
||||
if ($sTargetId) {
|
||||
$sTargetTmp=null;
|
||||
if (!$this->Poll_CheckTarget($sTargetType,$sTargetId)) {
|
||||
return 'Неверный тип объекта';
|
||||
}
|
||||
} else {
|
||||
$sTargetId=null;
|
||||
if (!$sTargetTmp or !$this->Poll_IsAllowTargetType($sTargetType)) {
|
||||
return 'Неверный тип объекта';
|
||||
}
|
||||
if ($this->Poll_GetPollByFilter(array('target_tmp'=>$sTargetTmp,'target_type <>'=>$sTargetType))) {
|
||||
return 'Временный идентификатор уже занят';
|
||||
}
|
||||
}
|
||||
|
||||
$this->setTargetType($sTargetType);
|
||||
$this->setTargetId($sTargetId);
|
||||
$this->setTargetTmp($sTargetTmp);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Проверяет доступность опроса для изменения
|
||||
* Важно понимать, что здесь нет проверки на права доступа
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isAllowUpdate() {
|
||||
$iTime=$this->getDateCreate();
|
||||
if ((time()-strtotime($iTime))>Config::Get('module.poll.time_limit_update')) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Проверяет возможность удаления опроса, не пользователем, а в принципе
|
||||
* Важно понимать, что здесь нет проверки на права доступа
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isAllowRemove() {
|
||||
if ($this->getCountVote() || $this->getCountAbstain()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Проверяет возможность голосования в опросе, не пользователем, а в принципе
|
||||
* Важно понимать, что здесь нет проверки на права доступа
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isAllowVote() {
|
||||
$sDateEnd=$this->getDateEnd();
|
||||
if ($sDateEnd and (time()-strtotime($sDateEnd))>0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getAnswerPercent($oAnswer) {
|
||||
$iCountAll=$this->getCountVote();
|
||||
if ($iCountAll==0) {
|
||||
return 0;
|
||||
} else {
|
||||
return number_format(round($oAnswer->getCountVote()*100/$iCountAll,1), 1, '.', '');
|
||||
}
|
||||
}
|
||||
|
||||
public function getCountVoteAnswerMax() {
|
||||
$iMax=0;
|
||||
$aAnswers=$this->getAnswers();
|
||||
foreach($aAnswers as $oAnswer) {
|
||||
if ($oAnswer->getCountVote()>$iMax) {
|
||||
$iMax=$oAnswer->getCountVote();
|
||||
}
|
||||
}
|
||||
return $iMax;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
<?php
|
||||
/**
|
||||
* LiveStreet CMS
|
||||
* Copyright © 2013 OOO "ЛС-СОФТ"
|
||||
*
|
||||
* ------------------------------------------------------
|
||||
*
|
||||
* Official site: www.livestreetcms.com
|
||||
* Contact e-mail: office@livestreetcms.com
|
||||
*
|
||||
* GNU General Public License, version 2:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
*
|
||||
* ------------------------------------------------------
|
||||
*
|
||||
* @link http://www.livestreetcms.com
|
||||
* @copyright 2013 OOO "ЛС-СОФТ"
|
||||
* @author Maxim Mzhelskiy <rus.engine@gmail.com>
|
||||
*
|
||||
*/
|
||||
|
||||
class ModulePoll_EntityVote extends EntityORM {
|
||||
|
||||
protected $aValidateRules=array(
|
||||
|
||||
);
|
||||
|
||||
protected $aRelations=array(
|
||||
'poll' => array(self::RELATION_TYPE_BELONGS_TO,'ModulePoll_EntityPoll','poll_id'),
|
||||
);
|
||||
|
||||
protected function beforeSave() {
|
||||
if ($this->_isNew()) {
|
||||
$this->setDateCreate(date("Y-m-d H:i:s"));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function afterSave() {
|
||||
if ($this->_isNew()) {
|
||||
/**
|
||||
* Отмечаем факт голосования в опросе и вариантах
|
||||
*/
|
||||
$oPoll=$this->getPoll();
|
||||
$aAnswerItems=$this->getAnswersObject();
|
||||
if ($aAnswerItems) {
|
||||
foreach($aAnswerItems as $oAnswer) {
|
||||
$oAnswer->setCountVote($oAnswer->getCountVote()+1);
|
||||
$oAnswer->Update();
|
||||
}
|
||||
$oPoll->setCountVote($oPoll->getCountVote()+1);
|
||||
} else {
|
||||
$oPoll->setCountAbstain($oPoll->getCountAbstain()+1);
|
||||
}
|
||||
$oPoll->Update(0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает список вариантов, за которые голосовали
|
||||
*
|
||||
* @return array|mixed
|
||||
*/
|
||||
public function getAnswers() {
|
||||
$aData=@unserialize($this->_getDataOne('answers'));
|
||||
if (!$aData) {
|
||||
$aData=array();
|
||||
}
|
||||
return $aData;
|
||||
}
|
||||
/**
|
||||
* Устанавливает список вариантов, за которые голосовали
|
||||
*
|
||||
* @param $aParams
|
||||
*/
|
||||
public function setAnswers($aParams) {
|
||||
$this->_aData['answers']=@serialize($aParams);
|
||||
}
|
||||
}
|
|
@ -336,11 +336,32 @@ class ModuleProperty extends ModuleORM {
|
|||
/**
|
||||
* Переопределяем метод для возможности цеплять свои кастомные данные при ORM запросах - свойства
|
||||
*
|
||||
* @param array $aEntitiesWork
|
||||
* @param array $aResult
|
||||
* @param array $aFilter
|
||||
* @param null|string $sEntityFull
|
||||
*/
|
||||
public function RewriteGetItemsByFilter($aEntitiesWork,$aFilter=array(),$sEntityFull=null) {
|
||||
public function RewriteGetItemsByFilter($aResult,$aFilter=array(),$sEntityFull=null) {
|
||||
if (!$aResult) {
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Список на входе может быть двух видом:
|
||||
* 1 - одномерный массив
|
||||
* 2 - двумерный, если применялась группировка (использование '#index-group')
|
||||
*
|
||||
* Поэтому сначала сформируем линейный список
|
||||
*/
|
||||
if (isset($aFilter['#index-group']) and $aFilter['#index-group']) {
|
||||
$aEntitiesWork=array();
|
||||
foreach($aResult as $aItems) {
|
||||
foreach($aItems as $oItem) {
|
||||
$aEntitiesWork[]=$oItem;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$aEntitiesWork=$aResult;
|
||||
}
|
||||
|
||||
if (!$aEntitiesWork) {
|
||||
return;
|
||||
}
|
||||
|
@ -729,4 +750,29 @@ class ModuleProperty extends ModuleORM {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function RemoveValueByPropertyId($iPropertyId) {
|
||||
$bRes=$this->oMapper->RemoveValueByPropertyId($iPropertyId);
|
||||
$this->Cache_Clean(Zend_Cache::CLEANING_MODE_MATCHING_TAG,array('ModuleProperty_EntityValue_delete'));
|
||||
return $bRes;
|
||||
}
|
||||
|
||||
public function RemoveValueTagByPropertyId($iPropertyId) {
|
||||
$bRes=$this->oMapper->RemoveValueTagByPropertyId($iPropertyId);
|
||||
$this->Cache_Clean(Zend_Cache::CLEANING_MODE_MATCHING_TAG,array('ModuleProperty_EntityValueTag_delete'));
|
||||
return $bRes;
|
||||
}
|
||||
|
||||
public function RemoveValueSelectByPropertyId($iPropertyId) {
|
||||
$bRes=$this->oMapper->RemoveValueSelectByPropertyId($iPropertyId);
|
||||
$this->Cache_Clean(Zend_Cache::CLEANING_MODE_MATCHING_TAG,array('ModuleProperty_EntityValueSelect_delete'));
|
||||
return $bRes;
|
||||
}
|
||||
|
||||
public function RemoveSelectByPropertyId($iPropertyId) {
|
||||
$bRes=$this->oMapper->RemoveSelectByPropertyId($iPropertyId);
|
||||
$this->Cache_Clean(Zend_Cache::CLEANING_MODE_MATCHING_TAG,array('ModuleProperty_EntitySelect_delete'));
|
||||
return $bRes;
|
||||
}
|
||||
|
||||
}
|
|
@ -94,6 +94,30 @@ class ModuleProperty_EntityProperty extends EntityORM {
|
|||
}
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Выполняется перед удалением сущности
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function beforeDelete() {
|
||||
/**
|
||||
* Сначала удаляем стандартные значения
|
||||
*/
|
||||
$this->Property_RemoveValueByPropertyId($this->getId());
|
||||
/**
|
||||
* Удаляем значения тегов
|
||||
*/
|
||||
$this->Property_RemoveValueTagByPropertyId($this->getId());
|
||||
/**
|
||||
* Удаляем значения селектов
|
||||
*/
|
||||
$this->Property_RemoveValueSelectByPropertyId($this->getId());
|
||||
/**
|
||||
* Удаляем сами варианты селектов
|
||||
*/
|
||||
$this->Property_RemoveSelectByPropertyId($this->getId());
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Возвращает правила валидации поля
|
||||
*
|
||||
|
|
|
@ -134,6 +134,54 @@ class ModuleProperty_MapperProperty extends Mapper {
|
|||
return false;
|
||||
}
|
||||
|
||||
public function RemoveValueByPropertyId($iPropertyId) {
|
||||
$sql = "DELETE
|
||||
FROM ".Config::Get('db.table.property_value')."
|
||||
WHERE
|
||||
property_id = ?d
|
||||
";
|
||||
if ($this->oDb->query($sql,$iPropertyId)!==false) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function RemoveValueTagByPropertyId($iPropertyId) {
|
||||
$sql = "DELETE
|
||||
FROM ".Config::Get('db.table.property_value_tag')."
|
||||
WHERE
|
||||
property_id = ?d
|
||||
";
|
||||
if ($this->oDb->query($sql,$iPropertyId)!==false) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function RemoveValueSelectByPropertyId($iPropertyId) {
|
||||
$sql = "DELETE
|
||||
FROM ".Config::Get('db.table.property_value_select')."
|
||||
WHERE
|
||||
property_id = ?d
|
||||
";
|
||||
if ($this->oDb->query($sql,$iPropertyId)!==false) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function RemoveSelectByPropertyId($iPropertyId) {
|
||||
$sql = "DELETE
|
||||
FROM ".Config::Get('db.table.property_select')."
|
||||
WHERE
|
||||
property_id = ?d
|
||||
";
|
||||
if ($this->oDb->query($sql,$iPropertyId)!==false) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function GetPropertyTagsByLike($sTag,$iPropertyId,$iLimit) {
|
||||
$sTag=mb_strtolower($sTag,"UTF-8");
|
||||
$sql = "SELECT
|
||||
|
|
|
@ -75,8 +75,7 @@ class ModuleTools extends Module {
|
|||
* @return string
|
||||
*/
|
||||
public function Urlspecialchars($sText) {
|
||||
func_urlspecialchars($sText);
|
||||
return $sText;
|
||||
return func_urlspecialchars($sText);
|
||||
}
|
||||
/**
|
||||
* Обработка тега ls в тексте
|
||||
|
|
|
@ -70,6 +70,17 @@ class ModuleTopic extends Module {
|
|||
public function GetTopicTypes($bOnlyCode=false) {
|
||||
return $bOnlyCode ? array_keys($this->aTopicTypes) : $this->aTopicTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает объект типа топика, поиск только среди активных типов
|
||||
*
|
||||
* @param string $sType
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
public function GetTopicType($sType) {
|
||||
return isset($this->aTopicTypes[$sType]) ? $this->aTopicTypes[$sType] : null;
|
||||
}
|
||||
/**
|
||||
* Проверяет разрешен ли данный тип топика
|
||||
*
|
||||
|
@ -103,7 +114,6 @@ class ModuleTopic extends Module {
|
|||
*/
|
||||
$aUserId=array();
|
||||
$aBlogId=array();
|
||||
$aTopicIdQuestion=array();
|
||||
foreach ($aTopics as $oTopic) {
|
||||
if (isset($aAllowData['user'])) {
|
||||
$aUserId[]=$oTopic->getUserId();
|
||||
|
@ -111,22 +121,17 @@ class ModuleTopic extends Module {
|
|||
if (isset($aAllowData['blog'])) {
|
||||
$aBlogId[]=$oTopic->getBlogId();
|
||||
}
|
||||
if ($oTopic->getType()=='question') {
|
||||
$aTopicIdQuestion[]=$oTopic->getId();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Получаем дополнительные данные
|
||||
*/
|
||||
$aTopicsVote=array();
|
||||
$aFavouriteTopics=array();
|
||||
$aTopicsQuestionVote=array();
|
||||
$aTopicsRead=array();
|
||||
$aUsers=isset($aAllowData['user']) && is_array($aAllowData['user']) ? $this->User_GetUsersAdditionalData($aUserId,$aAllowData['user']) : $this->User_GetUsersAdditionalData($aUserId);
|
||||
$aBlogs=isset($aAllowData['blog']) && is_array($aAllowData['blog']) ? $this->Blog_GetBlogsAdditionalData($aBlogId,$aAllowData['blog']) : $this->Blog_GetBlogsAdditionalData($aBlogId);
|
||||
if (isset($aAllowData['vote']) and $this->oUserCurrent) {
|
||||
$aTopicsVote=$this->Vote_GetVoteByArray($aTopicId,'topic',$this->oUserCurrent->getId());
|
||||
$aTopicsQuestionVote=$this->GetTopicsQuestionVoteByArray($aTopicIdQuestion,$this->oUserCurrent->getId());
|
||||
}
|
||||
if (isset($aAllowData['favourite']) and $this->oUserCurrent) {
|
||||
$aFavouriteTopics=$this->GetFavouriteTopicsByArray($aTopicId,$this->oUserCurrent->getId());
|
||||
|
@ -158,11 +163,6 @@ class ModuleTopic extends Module {
|
|||
} else {
|
||||
$oTopic->setFavourite(null);
|
||||
}
|
||||
if (isset($aTopicsQuestionVote[$oTopic->getId()])) {
|
||||
$oTopic->setUserQuestionIsVote(true);
|
||||
} else {
|
||||
$oTopic->setUserQuestionIsVote(false);
|
||||
}
|
||||
if (isset($aTopicsRead[$oTopic->getId()])) {
|
||||
$oTopic->setCountCommentNew($oTopic->getCountComment()-$aTopicsRead[$oTopic->getId()]->getCommentCountLast());
|
||||
$oTopic->setDateRead($aTopicsRead[$oTopic->getId()]->getDateRead());
|
||||
|
@ -1354,121 +1354,6 @@ class ModuleTopic extends Module {
|
|||
}
|
||||
return $data;
|
||||
}
|
||||
/**
|
||||
* Проверяет голосовал ли юзер за топик-вопрос
|
||||
*
|
||||
* @param int $sTopicId ID топика
|
||||
* @param int $sUserId ID пользователя
|
||||
* @return ModuleTopic_EntityTopicQuestionVote|null
|
||||
*/
|
||||
public function GetTopicQuestionVote($sTopicId,$sUserId) {
|
||||
$data=$this->GetTopicsQuestionVoteByArray($sTopicId,$sUserId);
|
||||
if (isset($data[$sTopicId])) {
|
||||
return $data[$sTopicId];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* Получить список голосований в топике-опросе по списку айдишников
|
||||
*
|
||||
* @param array $aTopicId Список ID топиков
|
||||
* @param int $sUserId ID пользователя
|
||||
* @return array
|
||||
*/
|
||||
public function GetTopicsQuestionVoteByArray($aTopicId,$sUserId) {
|
||||
if (!$aTopicId) {
|
||||
return array();
|
||||
}
|
||||
if (Config::Get('sys.cache.solid')) {
|
||||
return $this->GetTopicsQuestionVoteByArraySolid($aTopicId,$sUserId);
|
||||
}
|
||||
if (!is_array($aTopicId)) {
|
||||
$aTopicId=array($aTopicId);
|
||||
}
|
||||
$aTopicId=array_unique($aTopicId);
|
||||
$aTopicsQuestionVote=array();
|
||||
$aTopicIdNotNeedQuery=array();
|
||||
/**
|
||||
* Делаем мульти-запрос к кешу
|
||||
*/
|
||||
$aCacheKeys=func_build_cache_keys($aTopicId,'topic_question_vote_','_'.$sUserId);
|
||||
if (false !== ($data = $this->Cache_Get($aCacheKeys))) {
|
||||
/**
|
||||
* проверяем что досталось из кеша
|
||||
*/
|
||||
foreach ($aCacheKeys as $sValue => $sKey ) {
|
||||
if (array_key_exists($sKey,$data)) {
|
||||
if ($data[$sKey]) {
|
||||
$aTopicsQuestionVote[$data[$sKey]->getTopicId()]=$data[$sKey];
|
||||
} else {
|
||||
$aTopicIdNotNeedQuery[]=$sValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Смотрим каких топиков не было в кеше и делаем запрос в БД
|
||||
*/
|
||||
$aTopicIdNeedQuery=array_diff($aTopicId,array_keys($aTopicsQuestionVote));
|
||||
$aTopicIdNeedQuery=array_diff($aTopicIdNeedQuery,$aTopicIdNotNeedQuery);
|
||||
$aTopicIdNeedStore=$aTopicIdNeedQuery;
|
||||
if ($data = $this->oMapperTopic->GetTopicsQuestionVoteByArray($aTopicIdNeedQuery,$sUserId)) {
|
||||
foreach ($data as $oTopicVote) {
|
||||
/**
|
||||
* Добавляем к результату и сохраняем в кеш
|
||||
*/
|
||||
$aTopicsQuestionVote[$oTopicVote->getTopicId()]=$oTopicVote;
|
||||
$this->Cache_Set($oTopicVote, "topic_question_vote_{$oTopicVote->getTopicId()}_{$oTopicVote->getVoterId()}", array(), 60*60*24*4);
|
||||
$aTopicIdNeedStore=array_diff($aTopicIdNeedStore,array($oTopicVote->getTopicId()));
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Сохраняем в кеш запросы не вернувшие результата
|
||||
*/
|
||||
foreach ($aTopicIdNeedStore as $sId) {
|
||||
$this->Cache_Set(null, "topic_question_vote_{$sId}_{$sUserId}", array(), 60*60*24*4);
|
||||
}
|
||||
/**
|
||||
* Сортируем результат согласно входящему массиву
|
||||
*/
|
||||
$aTopicsQuestionVote=func_array_sort_by_keys($aTopicsQuestionVote,$aTopicId);
|
||||
return $aTopicsQuestionVote;
|
||||
}
|
||||
/**
|
||||
* Получить список голосований в топике-опросе по списку айдишников, но используя единый кеш
|
||||
*
|
||||
* @param array $aTopicId Список ID топиков
|
||||
* @param int $sUserId ID пользователя
|
||||
* @return array
|
||||
*/
|
||||
public function GetTopicsQuestionVoteByArraySolid($aTopicId,$sUserId) {
|
||||
if (!is_array($aTopicId)) {
|
||||
$aTopicId=array($aTopicId);
|
||||
}
|
||||
$aTopicId=array_unique($aTopicId);
|
||||
$aTopicsQuestionVote=array();
|
||||
$s=join(',',$aTopicId);
|
||||
if (false === ($data = $this->Cache_Get("topic_question_vote_{$sUserId}_id_{$s}"))) {
|
||||
$data = $this->oMapperTopic->GetTopicsQuestionVoteByArray($aTopicId,$sUserId);
|
||||
foreach ($data as $oTopicVote) {
|
||||
$aTopicsQuestionVote[$oTopicVote->getTopicId()]=$oTopicVote;
|
||||
}
|
||||
$this->Cache_Set($aTopicsQuestionVote, "topic_question_vote_{$sUserId}_id_{$s}", array("topic_question_vote_user_{$sUserId}"), 60*60*24*1);
|
||||
return $aTopicsQuestionVote;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
/**
|
||||
* Добавляет факт голосования за топик-вопрос
|
||||
*
|
||||
* @param ModuleTopic_EntityTopicQuestionVote $oTopicQuestionVote Объект голосования в топике-опросе
|
||||
* @return bool
|
||||
*/
|
||||
public function AddTopicQuestionVote(ModuleTopic_EntityTopicQuestionVote $oTopicQuestionVote) {
|
||||
$this->Cache_Delete("topic_question_vote_{$oTopicQuestionVote->getTopicId()}_{$oTopicQuestionVote->getVoterId()}");
|
||||
$this->Cache_Clean(Zend_Cache::CLEANING_MODE_MATCHING_TAG,array("topic_question_vote_user_{$oTopicQuestionVote->getVoterId()}"));
|
||||
return $this->oMapperTopic->AddTopicQuestionVote($oTopicQuestionVote);
|
||||
}
|
||||
/**
|
||||
* Получает топик по уникальному хешу(текст топика)
|
||||
*
|
||||
|
|
|
@ -383,14 +383,6 @@ class ModuleTopic_EntityTopic extends Entity {
|
|||
public function getVote() {
|
||||
return $this->_getDataOne('vote');
|
||||
}
|
||||
/**
|
||||
* Возвращает статус голосовал ли пользователь в топике-опросе
|
||||
*
|
||||
* @return bool|null
|
||||
*/
|
||||
public function getUserQuestionIsVote() {
|
||||
return $this->_getDataOne('user_question_is_vote');
|
||||
}
|
||||
/**
|
||||
* Проверяет находится ли данный топик в избранном у текущего пользователя
|
||||
*
|
||||
|
@ -463,6 +455,29 @@ class ModuleTopic_EntityTopic extends Entity {
|
|||
public function getPropertyTargetType() {
|
||||
return 'topic_'.$this->getType();
|
||||
}
|
||||
/**
|
||||
* Возвращает объект типа топика
|
||||
*
|
||||
* @return ModuleTopic_EntityTopicType|null
|
||||
*/
|
||||
public function getTypeObject() {
|
||||
if (!$this->_getDataOne('type_object')) {
|
||||
$this->_aData['type_object']=$this->Topic_GetTopicTypeByCode($this->getType());
|
||||
}
|
||||
return $this->_getDataOne('type_object');
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает список опросов, которые есть у топика
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
public function getPolls() {
|
||||
if (!$this->_getDataOne('polls')) {
|
||||
$this->_aData['polls']=$this->Poll_GetPollItemsByTarget('topic',$this->getId());
|
||||
}
|
||||
return $this->_getDataOne('polls');
|
||||
}
|
||||
|
||||
/***************************************************************************************************************************************************
|
||||
* методы расширения типов топика
|
||||
|
@ -567,141 +582,6 @@ class ModuleTopic_EntityTopic extends Entity {
|
|||
$this->setExtraValue('count_jump',$data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Добавляет вариант ответа в топик-опрос
|
||||
*
|
||||
* @param string $data
|
||||
*/
|
||||
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->setExtraValue('answers',array());
|
||||
}
|
||||
/**
|
||||
* Возвращает варианты ответа в топике-опрос
|
||||
*
|
||||
* @param bool $bSortVote
|
||||
* @return array|null
|
||||
*/
|
||||
public function getQuestionAnswers($bSortVote=false) {
|
||||
if ($this->getType()!='question') {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($this->getExtraValue('answers')) {
|
||||
$aAnswers=$this->getExtraValue('answers');
|
||||
if ($bSortVote) {
|
||||
uasort($aAnswers, create_function('$a,$b',"if (\$a['count'] == \$b['count']) { return 0; } return (\$a['count'] < \$b['count']) ? 1 : -1;"));
|
||||
}
|
||||
return $aAnswers;
|
||||
}
|
||||
return array();
|
||||
}
|
||||
/**
|
||||
* Увеличивает количество ответов на данный вариант в топике-опросе
|
||||
*
|
||||
* @param int $sIdAnswer ID варианта ответа
|
||||
*/
|
||||
public function increaseQuestionAnswerVote($sIdAnswer) {
|
||||
if ($aAnswers=$this->getQuestionAnswers()) {
|
||||
if (isset($aAnswers[$sIdAnswer])) {
|
||||
$aAnswers[$sIdAnswer]['count']++;
|
||||
$this->aExtra['answers']=$aAnswers;
|
||||
$this->setExtra($this->aExtra);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Возвращает максимально количество ответов на вариант в топике-опросе
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getQuestionAnswerMax() {
|
||||
$aAnswers=$this->getQuestionAnswers();
|
||||
$iMax=0;
|
||||
foreach ($aAnswers as $aAns) {
|
||||
if ($aAns['count']>$iMax) {
|
||||
$iMax=$aAns['count'];
|
||||
}
|
||||
}
|
||||
return $iMax;
|
||||
}
|
||||
/**
|
||||
* Возвращает в процентах количество проголосовавших за конкретный вариант
|
||||
*
|
||||
* @param int $sIdAnswer ID варианта
|
||||
* @return int|string
|
||||
*/
|
||||
public function getQuestionAnswerPercent($sIdAnswer) {
|
||||
if ($aAnswers=$this->getQuestionAnswers()) {
|
||||
if (isset($aAnswers[$sIdAnswer])) {
|
||||
$iCountAll=$this->getQuestionCountVote()-$this->getQuestionCountVoteAbstain();
|
||||
if ($iCountAll==0) {
|
||||
return 0;
|
||||
} else {
|
||||
return number_format(round($aAnswers[$sIdAnswer]['count']*100/$iCountAll,1), 1, '.', '');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Возвращает общее число принявших участие в опросе в топике-опросе
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
public function getQuestionCountVote() {
|
||||
if ($this->getType()!='question') {
|
||||
return null;
|
||||
}
|
||||
return (int)$this->getExtraValue('count_vote');
|
||||
}
|
||||
/**
|
||||
* Устанавливает общее число принявших участие в опросе в топике-опросе
|
||||
*
|
||||
* @param int $data
|
||||
*/
|
||||
public function setQuestionCountVote($data) {
|
||||
if ($this->getType()!='question') {
|
||||
return;
|
||||
}
|
||||
$this->setExtraValue('count_vote',$data);
|
||||
}
|
||||
/**
|
||||
* Возвращает число воздержавшихся от участия в опросе в топике-опросе
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
public function getQuestionCountVoteAbstain() {
|
||||
if ($this->getType()!='question') {
|
||||
return null;
|
||||
}
|
||||
return (int)$this->getExtraValue('count_vote_abstain');
|
||||
}
|
||||
/**
|
||||
* Устанавливает число воздержавшихся от участия в опросе в топике-опросе
|
||||
*
|
||||
* @param int $data
|
||||
* @return mixed
|
||||
*/
|
||||
public function setQuestionCountVoteAbstain($data) {
|
||||
if ($this->getType()!='question') {
|
||||
return;
|
||||
}
|
||||
$this->setExtraValue('count_vote_abstain',$data);
|
||||
}
|
||||
|
||||
|
||||
//*************************************************************************************************************************************************
|
||||
|
||||
|
|
|
@ -32,10 +32,21 @@ class ModuleTopic_EntityTopicType extends Entity {
|
|||
array('name, name_many','string','max'=>200,'min'=>1,'allowEmpty'=>false),
|
||||
array('code','regexp','pattern'=>"#^[a-z0-9_]{1,30}$#",'allowEmpty'=>false),
|
||||
array('code','code_unique'),
|
||||
array('params','check_params'),
|
||||
array('name','check_name'),
|
||||
array('name_many','check_name_many'),
|
||||
);
|
||||
|
||||
public function ValidateCheckParams() {
|
||||
$aParamsResult=array();
|
||||
$aParams=$this->getParamsArray();
|
||||
|
||||
$aParamsResult['allow_poll']=(isset($aParams['allow_poll']) and $aParams['allow_poll']) ? true : false;
|
||||
|
||||
$this->setParams($aParamsResult);
|
||||
return true;
|
||||
}
|
||||
|
||||
public function ValidateCheckName() {
|
||||
$this->setName(htmlspecialchars($this->getName()));
|
||||
return true;
|
||||
|
@ -82,7 +93,7 @@ class ModuleTopic_EntityTopicType extends Entity {
|
|||
* @return null
|
||||
*/
|
||||
public function getParam($sName) {
|
||||
$aParams=$this->getParams();
|
||||
$aParams=$this->getParamsArray();
|
||||
return isset($aParams[$sName]) ? $aParams[$sName] : null;
|
||||
}
|
||||
|
||||
|
|
|
@ -692,55 +692,6 @@ class ModuleTopic_MapperTopic extends Mapper {
|
|||
}
|
||||
return $aReads;
|
||||
}
|
||||
/**
|
||||
* Добавляет факт голосования за топик-вопрос
|
||||
*
|
||||
* @param ModuleTopic_EntityTopicQuestionVote $oTopicQuestionVote Объект голосования в топике-опросе
|
||||
* @return bool
|
||||
*/
|
||||
public function AddTopicQuestionVote(ModuleTopic_EntityTopicQuestionVote $oTopicQuestionVote) {
|
||||
$sql = "INSERT INTO ".Config::Get('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;
|
||||
}
|
||||
/**
|
||||
* Получить список голосований в топике-опросе по списку айдишников
|
||||
*
|
||||
* @param array $aArrayId Список ID топиков
|
||||
* @param int $sUserId ID пользователя
|
||||
* @return array
|
||||
*/
|
||||
public function GetTopicsQuestionVoteByArray($aArrayId,$sUserId) {
|
||||
if (!is_array($aArrayId) or count($aArrayId)==0) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$sql = "SELECT
|
||||
v.*
|
||||
FROM
|
||||
".Config::Get('db.table.topic_question_vote')." as v
|
||||
WHERE
|
||||
v.topic_id IN(?a)
|
||||
AND
|
||||
v.user_voter_id = ?d
|
||||
";
|
||||
$aVotes=array();
|
||||
if ($aRows=$this->oDb->select($sql,$aArrayId,$sUserId)) {
|
||||
foreach ($aRows as $aRow) {
|
||||
$aVotes[]=Engine::GetEntity('Topic_TopicQuestionVote',$aRow);
|
||||
}
|
||||
}
|
||||
return $aVotes;
|
||||
}
|
||||
/**
|
||||
* Перемещает топики в другой блог
|
||||
*
|
||||
|
|
|
@ -205,6 +205,10 @@ $config['module']['wall']['per_page'] = 10; // Число сообщени
|
|||
$config['module']['wall']['text_max'] = 250; // Ограничение на максимальное количество символов в одном сообщении на стене
|
||||
$config['module']['wall']['text_min'] = 1; // Ограничение на минимальное количество символов в одном сообщении на стене
|
||||
|
||||
/**
|
||||
* Модуль опросов (Poll)
|
||||
*/
|
||||
$config['module']['poll']['time_limit_update'] = 60*60*30; // Время в секундах, в течении которого можно изменять опрос
|
||||
/**
|
||||
* Модуль Media
|
||||
*/
|
||||
|
@ -267,7 +271,6 @@ $config['db']['table']['talk_user'] = '___db.table.prefix___talk_user'
|
|||
$config['db']['table']['talk_blacklist'] = '___db.table.prefix___talk_blacklist';
|
||||
$config['db']['table']['friend'] = '___db.table.prefix___friend';
|
||||
$config['db']['table']['topic_content'] = '___db.table.prefix___topic_content';
|
||||
$config['db']['table']['topic_question_vote'] = '___db.table.prefix___topic_question_vote';
|
||||
$config['db']['table']['user_administrator'] = '___db.table.prefix___user_administrator';
|
||||
$config['db']['table']['comment_online'] = '___db.table.prefix___comment_online';
|
||||
$config['db']['table']['invite'] = '___db.table.prefix___invite';
|
||||
|
@ -303,6 +306,9 @@ $config['db']['table']['rbac_permission'] = '___db.table.prefix___rbac_permis
|
|||
$config['db']['table']['rbac_role_permission']= '___db.table.prefix___rbac_role_permission';
|
||||
$config['db']['table']['rbac_user_role'] = '___db.table.prefix___rbac_user_role';
|
||||
$config['db']['table']['storage'] = '___db.table.prefix___storage';
|
||||
$config['db']['table']['poll'] = '___db.table.prefix___poll';
|
||||
$config['db']['table']['poll_answer'] = '___db.table.prefix___poll_answer';
|
||||
$config['db']['table']['poll_vote'] = '___db.table.prefix___poll_vote';
|
||||
|
||||
$config['db']['tables']['engine'] = 'InnoDB'; // InnoDB или MyISAM
|
||||
|
||||
|
@ -467,6 +473,7 @@ $config['head']['default']['js'] = array(
|
|||
"___path.framework.frontend.web___/js/vendor/parsley/i18n/messages.ru.js",
|
||||
"___path.framework.frontend.web___/js/vendor/jquery.livequery.js",
|
||||
"___path.framework.frontend.web___/js/vendor/fotorama/fotorama.js",
|
||||
"___path.framework.frontend.web___/js/vendor/nprogress/nprogress.js",
|
||||
|
||||
/* Core */
|
||||
"___path.framework.frontend.web___/js/core/main.js",
|
||||
|
|
|
@ -16,7 +16,7 @@ ls.poll = (function ($) {
|
|||
*/
|
||||
var defaults = {
|
||||
// Роутер голосования
|
||||
sRouterVoteUrl: aRouter['ajax'] + 'vote/question/',
|
||||
sRouterVoteUrl: aRouter['ajax'] + 'poll/vote/',
|
||||
|
||||
// Максимальное кол-во вариантов ответов
|
||||
iMaxItems: 20,
|
||||
|
@ -31,8 +31,6 @@ ls.poll = (function ($) {
|
|||
|
||||
// Селекторы опроса
|
||||
sPollSelector: '.js-poll',
|
||||
sPollListSelector: '.js-poll-list',
|
||||
sPollItemSelector: '.js-poll-item',
|
||||
sPollItemOptionSelector: '.js-poll-item-option',
|
||||
sPollButtonVoteSelector: '.js-poll-button-vote',
|
||||
sPollButtonAbstainSelector: '.js-poll-button-abstain',
|
||||
|
@ -44,11 +42,16 @@ ls.poll = (function ($) {
|
|||
|
||||
// Html варианта ответа
|
||||
sAddItemHtml: '<li class="poll-add-item js-poll-add-item">' +
|
||||
'<input type="text" name="answer[]" class="poll-add-item-input js-poll-add-item-input">' +
|
||||
'<input type="checkbox" disabled="disabled">' +
|
||||
'<input type="hidden" name="answers[_NUMBER_][id]" value="_ANSWER_ID_">' +
|
||||
'<input type="text" name="answers[_NUMBER_][title]" class="poll-add-item-input js-poll-add-item-input" value="_ANSWER_TITLE_">' +
|
||||
'<i class="icon-remove poll-add-item-remove js-poll-add-item-remove" title="' + ls.lang.get('delete') + '"></i>' +
|
||||
'</li>'
|
||||
};
|
||||
|
||||
this.aAnswersInit=[];
|
||||
this.iCountAnswers=0;
|
||||
|
||||
/**
|
||||
* Инициализация
|
||||
*
|
||||
|
@ -59,7 +62,42 @@ ls.poll = (function ($) {
|
|||
|
||||
this.options = $.extend({}, defaults, options);
|
||||
|
||||
// Добавление
|
||||
$(this.options.sPollSelector).each(function () {
|
||||
var oPoll = $(this),
|
||||
iPollId = oPoll.data('poll-id');
|
||||
|
||||
// Голосование за вариант
|
||||
oPoll.find(self.options.sPollButtonVoteSelector).on('click', function () {
|
||||
var form = oPoll.find('form');
|
||||
|
||||
self.vote(form,this);
|
||||
});
|
||||
// Воздержаться
|
||||
oPoll.find(self.options.sPollButtonAbstainSelector).on('click', function () {
|
||||
var form = oPoll.find('form');
|
||||
|
||||
self.vote(form,this,true);
|
||||
});
|
||||
// Сортировка
|
||||
oPoll.on('click', self.options.sPollResultButtonSortSelector, function () {
|
||||
self.toggleSort(oPoll);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
this.initFormUpdate = function() {
|
||||
this.initFormCreate();
|
||||
};
|
||||
|
||||
this.initFormCreate = function() {
|
||||
var self = this;
|
||||
|
||||
var oPollAdd=$('#form-poll-create').find(self.options.sAddSelector);
|
||||
$.each(self.aAnswersInit,function(k,v){
|
||||
self.addItem(oPollAdd,v);
|
||||
});
|
||||
|
||||
|
||||
$(this.options.sAddSelector).each(function () {
|
||||
var oPollAdd = $(this);
|
||||
|
||||
|
@ -82,33 +120,35 @@ ls.poll = (function ($) {
|
|||
self.removeItem(this);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// Голосование
|
||||
$(this.options.sPollSelector).each(function () {
|
||||
var oPoll = $(this),
|
||||
iPollId = oPoll.data('poll-id');
|
||||
this.createPoll = function(form,button) {
|
||||
ls.ajax.submit(aRouter.ajax+'poll/create/', form, function(result){
|
||||
$('#poll-form-items').append(result.sPollItem);
|
||||
|
||||
// Голосование за вариант
|
||||
oPoll.find(self.options.sPollButtonVoteSelector).on('click', function () {
|
||||
var iCheckedItemId = oPoll.find(self.options.sPollItemOptionSelector + ':checked').val();
|
||||
$('#modal-poll-create').modal('hide');
|
||||
},{ submitButton: $(button) });
|
||||
};
|
||||
|
||||
if (iCheckedItemId) {
|
||||
self.vote(iPollId, iCheckedItemId);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
this.updatePoll = function(form,button) {
|
||||
ls.ajax.submit(aRouter.ajax+'poll/update/', form, function(result){
|
||||
$('#poll-form-item-'+result.iPollId).replaceWith(result.sPollItem);
|
||||
|
||||
// Воздержаться
|
||||
oPoll.find(self.options.sPollButtonAbstainSelector).on('click', function () {
|
||||
self.vote(iPollId, -1);
|
||||
});
|
||||
$('#modal-poll-create').modal('hide');
|
||||
},{ submitButton: $(button) });
|
||||
};
|
||||
|
||||
// Воздержаться
|
||||
oPoll.on('click', self.options.sPollResultButtonSortSelector, function () {
|
||||
self.toggleSort(oPoll);
|
||||
});
|
||||
this.removePoll = function(id,tmp) {
|
||||
ls.ajax.load(aRouter.ajax+'poll/remove/', { id: id, tmp: tmp }, function(result){
|
||||
if (result.bStateError) {
|
||||
ls.msg.error(null, result.sMsg);
|
||||
} else {
|
||||
$('#poll-form-item-'+id).fadeOut('slow', function() {
|
||||
$(this).remove();
|
||||
});
|
||||
}
|
||||
});
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -116,17 +156,48 @@ ls.poll = (function ($) {
|
|||
*
|
||||
* @param {Object} oPollAdd Блок добавления опроса
|
||||
*/
|
||||
this.addItem = function(oPollAdd) {
|
||||
this.addItem = function(oPollAdd,params) {
|
||||
var defaults = {
|
||||
number: "0",
|
||||
answer_id: '',
|
||||
answer_title: '',
|
||||
disable_remove: false,
|
||||
disable_update: false
|
||||
}
|
||||
params = $.extend({}, defaults, params);
|
||||
|
||||
if(oPollAdd.find(this.options.sAddItemSelector).length == this.options.iMaxItems) {
|
||||
ls.msg.error(null, ls.lang.get('topic_question_create_answers_error_max'));
|
||||
return false;
|
||||
}
|
||||
|
||||
var self = this,
|
||||
oNewItem = $(this.options.sAddItemHtml);
|
||||
sTpl = this.options.sAddItemHtml;
|
||||
|
||||
sTpl = sTpl.replace(/_NUMBER_/g, this.iCountAnswers);
|
||||
sTpl = sTpl.replace(/_ANSWER_ID_/g, params.answer_id);
|
||||
sTpl = sTpl.replace(/_ANSWER_TITLE_/g, params.answer_title);
|
||||
|
||||
|
||||
oNewItem = $(sTpl);
|
||||
if (params.disable_remove) {
|
||||
oNewItem.find(this.options.sAddItemRemoveSelector).remove();
|
||||
}
|
||||
if (params.disable_update) {
|
||||
oNewItem.find(this.options.sAddItemInputSelector).attr('disabled','disabled');
|
||||
}
|
||||
|
||||
oPollAdd.find(this.options.sAddListSelector).append(oNewItem);
|
||||
oNewItem.find('input[type=text]').focus();
|
||||
this.iCountAnswers++;
|
||||
};
|
||||
|
||||
this.addItemInit = function(params) {
|
||||
this.aAnswersInit.push(params);
|
||||
};
|
||||
|
||||
this.clearItemInit = function() {
|
||||
this.aAnswersInit=[];
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -141,29 +212,21 @@ ls.poll = (function ($) {
|
|||
/**
|
||||
* Голосование в опросе
|
||||
*
|
||||
* @param {Number} iPollId ID опроса
|
||||
* @param {Number} iItemId ID выбранного пункта
|
||||
* @param {Object} form Форма с данными опроса
|
||||
* @param {Object} button Копка для анимации загрузки
|
||||
*/
|
||||
this.vote = function(iPollId, iItemId) {
|
||||
var oParams = {
|
||||
idTopic: iPollId,
|
||||
idAnswer: iItemId
|
||||
};
|
||||
this.vote = function(form,button,abstain) {
|
||||
form=$(form);
|
||||
var formData=form.serializeJSON();
|
||||
|
||||
ls.hook.marker('voteBefore');
|
||||
|
||||
ls.ajax.load(this.options.sRouterVoteUrl, oParams, function(result) {
|
||||
if (result.bStateError) {
|
||||
ls.msg.error(null, result.sMsg);
|
||||
} else {
|
||||
var oPoll = $('[data-poll-id=' + iPollId + ']');
|
||||
oPoll.html(result.sText);
|
||||
ls.ajax.submit(this.options.sRouterVoteUrl, form, function(result){
|
||||
var oPoll = $('[data-poll-id=' + formData.id + ']');
|
||||
oPoll.html(result.sText);
|
||||
|
||||
ls.msg.notice(null, result.sMsg);
|
||||
|
||||
ls.hook.run('ls_pool_vote_after', [iPollId, iItemId, result], oPoll);
|
||||
}
|
||||
});
|
||||
ls.hook.run('ls_pool_vote_after', [form, result], oPoll);
|
||||
}, { submitButton: $(button), params: { abstain: abstain ? 1 : 0 } });
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -32,8 +32,7 @@ return array(
|
|||
'form_reset' => 'Очистить форму',
|
||||
'error' => array(
|
||||
'save' => 'Ошибка сохранения',
|
||||
'add' => 'Произошла ошибка при добавлении',
|
||||
'remove' => 'Произошла ошибка при удалении',
|
||||
'remove' => 'При удалении возникла ошибка',
|
||||
'system' => array(
|
||||
'code' => array(
|
||||
'404' => 'К сожалению, такой страницы не существует. Вероятно, она была удалена с сервера, либо ее здесь никогда не было.',
|
||||
|
@ -44,8 +43,7 @@ return array(
|
|||
),
|
||||
'success' => array(
|
||||
'save' => 'Успешно сохранено',
|
||||
'add' => 'Успешно добавлено',
|
||||
'remove' => 'Успешно удалено',
|
||||
'remove' => 'Удаление прошло успешно',
|
||||
)
|
||||
),
|
||||
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
<div id="poll-form-items">
|
||||
{if $aPollItems}
|
||||
{foreach $aPollItems as $oPoll}
|
||||
{include file="polls/poll.form.item.tpl" oPoll=$oPoll}
|
||||
{/foreach}
|
||||
{/if}
|
||||
</div>
|
|
@ -104,13 +104,21 @@
|
|||
|
||||
{* Показывает дополнительные поля *}
|
||||
{$aBlockParams = []}
|
||||
{$aBlockParams.target_type = 'topic_'|cat:$sTopicType}
|
||||
{$aBlockParams.target_type = 'topic_'|cat:$oTopicType->getCode()}
|
||||
{if $oTopicEdit}
|
||||
{$aBlockParams.target_id = $oTopicEdit->getId()}
|
||||
{/if}
|
||||
|
||||
{insert name="block" block="propertyUpdate" params=$aBlockParams}
|
||||
|
||||
{* Вставка опросов *}
|
||||
{if $oTopicType->getParam('allow_poll')}
|
||||
{include file='polls/poll.form.inject.tpl'
|
||||
sTargetType = 'topic'
|
||||
sTargetId = {($oTopicEdit) ? $oTopicEdit->getId() : '' }
|
||||
}
|
||||
{/if}
|
||||
|
||||
{* Запретить комментарии *}
|
||||
{include file='forms/fields/form.field.checkbox.tpl'
|
||||
sFieldName = 'topic[topic_forbid_comment]'
|
||||
|
@ -134,7 +142,7 @@
|
|||
|
||||
|
||||
{* Скрытые поля *}
|
||||
{include file='forms/fields/form.field.hidden.tpl' sFieldName='topic_type' sFieldValue=$sTopicType}
|
||||
{include file='forms/fields/form.field.hidden.tpl' sFieldName='topic_type' sFieldValue=$oTopicType->getCode()}
|
||||
|
||||
|
||||
{* Кнопки *}
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
{**
|
||||
* Создание опроса
|
||||
*
|
||||
* @styles css/modals.css
|
||||
*}
|
||||
|
||||
{extends file='modals/modal_base.tpl'}
|
||||
|
||||
{block name='modal_id'}modal-poll-create{/block}
|
||||
{block name='modal_class'}modal-poll-create js-modal-default{/block}
|
||||
{block name='modal_title'}{if $oPoll}Редактирование опроса{else}Создание опроса{/if}{/block}
|
||||
|
||||
{block name='modal_content'}
|
||||
<form action="" method="post" onsubmit="return false;" id="form-poll-create">
|
||||
|
||||
{* Заголовок топика *}
|
||||
{include file='forms/fields/form.field.text.tpl'
|
||||
sFieldName = 'poll[title]'
|
||||
sFieldValue = {($oPoll) ? $oPoll->getTitle() : '' }
|
||||
sFieldLabel = 'Название опроса'}
|
||||
|
||||
{if $oPoll and $oPoll->getCountVote()}
|
||||
{$bDisableChangeType=true}
|
||||
{/if}
|
||||
|
||||
Пользователь может выбрать:
|
||||
<label><input type="radio" name="poll[type]" value="one" {if !$oPoll or $oPoll->getCountAnswerMax()==1}checked="checked"{/if} {if $bDisableChangeType}disabled="disabled"{/if}> один вариант</label>
|
||||
<label><input type="radio" name="poll[type]" value="many" {if $oPoll and $oPoll->getCountAnswerMax()>1}checked="checked"{/if} {if $bDisableChangeType}disabled="disabled"{/if}>
|
||||
несколько вариантов
|
||||
</label>
|
||||
{include file='forms/fields/form.field.text.tpl'
|
||||
sFieldName = 'poll[count_answer_max]'
|
||||
sFieldValue = {($oPoll) ? $oPoll->getCountAnswerMax() : 2 }
|
||||
bFieldIsDisabled = $bDisableChangeType }
|
||||
|
||||
<div class="fieldset poll-add js-poll-add">
|
||||
<header class="fieldset-header">
|
||||
<h3 class="fieldset-title">{$aLang.topic_question_create_answers}</h3>
|
||||
</header>
|
||||
|
||||
<ul class="fieldset-body poll-add-list js-poll-add-list">
|
||||
<script type="text/javascript">
|
||||
ls.poll.clearItemInit();
|
||||
{if $oPoll}
|
||||
{$aAnswers=$oPoll->getAnswers()}
|
||||
{foreach $aAnswers as $oAnswer}
|
||||
ls.poll.addItemInit({
|
||||
'answer_title': {json var=$oAnswer->getTitle()},
|
||||
'answer_id': {json var=$oAnswer->getId()},
|
||||
'disable_update': {json var=!$oPoll->isAllowUpdate()},
|
||||
'disable_remove': {json var=(!$oPoll->isAllowUpdate() || $oAnswer->getCountVote()) } });
|
||||
{/foreach}
|
||||
{else}
|
||||
ls.poll.addItemInit({ });
|
||||
{/if}
|
||||
</script>
|
||||
</ul>
|
||||
|
||||
{if !$oPoll or $oPoll->isAllowUpdate()}
|
||||
<footer class="fieldset-footer">
|
||||
<button type="button" class="button button-primary js-poll-add-button" title="[Ctrl + Enter]">{$aLang.topic_question_create_answers_add}</button>
|
||||
</footer>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
|
||||
{if $oPoll}
|
||||
{include file='forms/fields/form.field.hidden.tpl' sFieldName='poll_id' sFieldValue=$oPoll->getId()}
|
||||
{else}
|
||||
{include file='forms/fields/form.field.hidden.tpl' sFieldName='target[type]' sFieldValue=$sTargetType}
|
||||
{include file='forms/fields/form.field.hidden.tpl' sFieldName='target[id]' sFieldValue=$sTargetId}
|
||||
{/if}
|
||||
|
||||
{include file='forms/fields/form.field.hidden.tpl' sFieldName='target[tmp]' sFieldValue=$sTargetTmp}
|
||||
</form>
|
||||
{/block}
|
||||
|
||||
{block name='modal_footer_begin'}
|
||||
<button type="submit" class="button button-primary" onclick="{if $oPoll}ls.poll.updatePoll('#form-poll-create',this);{else}ls.poll.createPoll('#form-poll-create',this);{/if}">{if $oPoll}{$aLang.common.save}{else}{$aLang.common.add}{/if}</button>
|
||||
{/block}
|
|
@ -0,0 +1,9 @@
|
|||
<div>
|
||||
<a href="#" data-type="modal-toggle" data-modal-url="{router page='ajax/poll/modal-create'}" data-modal-aftershow="ls.poll.initFormCreate();" data-param-target_type="{$sTargetType}" data-param-target_id="{$sTargetId}">Добавить опрос</a>
|
||||
|
||||
{$aBlockParams = []}
|
||||
{$aBlockParams.target_type = $sTargetType}
|
||||
{$aBlockParams.target_id = $sTargetId}
|
||||
|
||||
{insert name="block" block="pollFormItems" params=$aBlockParams}
|
||||
</div>
|
|
@ -0,0 +1,5 @@
|
|||
<div id="poll-form-item-{$oPoll->getId()}">
|
||||
Опрос: {$oPoll->getTitle()} —
|
||||
<a href="#" data-type="modal-toggle" data-modal-url="{router page='ajax/poll/modal-update'}" data-modal-aftershow="ls.poll.initFormUpdate();" data-param-id="{$oPoll->getId()}" data-param-target_tmp="{$oPoll->getTargetTmp()}">{$aLang.common.edit}</a>
|
||||
<a href="#" onclick="return ls.poll.removePoll({$oPoll->getId()},'{$oPoll->getTargetTmp()}');">{$aLang.common.remove}</a>
|
||||
</div>
|
32
application/frontend/skin/developer/polls/poll.list.tpl
Normal file
32
application/frontend/skin/developer/polls/poll.list.tpl
Normal file
|
@ -0,0 +1,32 @@
|
|||
{foreach $aPollItems as $oPollItem}
|
||||
|
||||
<div class="poll poll-type-{$oPollItem->getTargetType()} js-poll" data-poll-id="{$oPollItem->getId()}" data-poll-answer-max="{$oPollItem->getCountAnswerMax()}">
|
||||
{$oPollItem->getTitle()}
|
||||
|
||||
{if !$oPollItem->getVoteCurrent()}
|
||||
<form action="" method="post" onsubmit="return false;">
|
||||
<ul class="poll-list">
|
||||
{foreach $oPollItem->getAnswers() as $oAnswer}
|
||||
<li class="poll-item">
|
||||
<label>
|
||||
{if $oPollItem->getCountAnswerMax()>1}
|
||||
<input type="checkbox" name="answers[]" value="{$oAnswer->getId()}" />
|
||||
{else}
|
||||
<input type="radio" name="answers[]" value="{$oAnswer->getId()}" />
|
||||
{/if}
|
||||
{$oAnswer->getTitle()}
|
||||
</label>
|
||||
</li>
|
||||
{/foreach}
|
||||
</ul>
|
||||
|
||||
<input type="hidden" name="id" value="{$oPollItem->getId()}">
|
||||
<button type="submit" class="button button-primary js-poll-button-vote">Голосовать</button>
|
||||
<button type="submit" class="button js-poll-button-abstain">Воздержаться</button>
|
||||
</form>
|
||||
{else}
|
||||
{include file='polls/poll.result.tpl' oPoll=$oPollItem}
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
{/foreach}
|
35
application/frontend/skin/developer/polls/poll.result.tpl
Normal file
35
application/frontend/skin/developer/polls/poll.result.tpl
Normal file
|
@ -0,0 +1,35 @@
|
|||
{**
|
||||
* Результат опроса
|
||||
*
|
||||
* @styles assets/css/poll.css
|
||||
* @scripts <framework>/js/livestreet/poll.js
|
||||
*}
|
||||
|
||||
{$oPoll->getTitle()}
|
||||
|
||||
<ul class="poll-result js-poll-result">
|
||||
{$aAnswerItems=$oPoll->getAnswers()}
|
||||
{$iPollItemsCount = count($aAnswerItems)}
|
||||
|
||||
{foreach $aAnswerItems as $oAnswer}
|
||||
<li class="poll-result-item {if $oPoll->getCountVoteAnswerMax() == $oAnswer->getCountVote()}poll-result-item-most{/if} js-poll-result-item"
|
||||
data-poll-item-count="{$oAnswer->getCountVote()}"
|
||||
data-poll-item-pos="{$iPollItemsCount - $oAnswer@index - 1}">
|
||||
|
||||
<div class="poll-result-item-count">
|
||||
<strong>{$oPoll->getAnswerPercent($oAnswer)}%</strong>
|
||||
<span>({$oAnswer->getCountVote()})</span>
|
||||
</div>
|
||||
|
||||
<div class="poll-result-item-chart">
|
||||
<div class="poll-result-item-label">{$oAnswer->getTitle()}</div>
|
||||
<div class="poll-result-item-bar" style="width: {$oPoll->getAnswerPercent($oAnswer)}%;" ></div>
|
||||
</div>
|
||||
</li>
|
||||
{/foreach}
|
||||
</ul>
|
||||
|
||||
{* Кнопка сортировки *}
|
||||
<button class="button button-icon js-poll-result-button-sort" title="Включить\выключить сортировку"><i class="icon-align-left"></i></button>
|
||||
|
||||
<span class="poll-result-total">Проголосовало: {$oPoll->getCountVote()} | Воздержалось: {$oPoll->getCountAbstain()}</span>
|
|
@ -34,6 +34,7 @@ $aCss=array(
|
|||
"___path.framework.frontend.web___/js/vendor/prettyphoto/css/prettyphoto.css",
|
||||
"___path.framework.frontend.web___/js/vendor/notifier/jquery.notifier.css",
|
||||
"___path.framework.frontend.web___/js/vendor/fotorama/fotorama.css",
|
||||
"___path.framework.frontend.web___/js/vendor/nprogress/nprogress.css",
|
||||
"___path.skin.assets.web___/css/grid.css",
|
||||
"___path.skin.assets.web___/css/forms.css",
|
||||
"___path.skin.assets.web___/css/common.css",
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
{**
|
||||
* Результат опроса
|
||||
*
|
||||
* @styles assets/css/poll.css
|
||||
* @scripts <framework>/js/livestreet/poll.js
|
||||
*}
|
||||
|
||||
<ul class="poll-result js-poll-result">
|
||||
{$iPollItemsCount = count($oTopic->getQuestionAnswers())}
|
||||
|
||||
{foreach $oTopic->getQuestionAnswers() as $aAnswer}
|
||||
<li class="poll-result-item {if $oTopic->getQuestionAnswerMax() == $aAnswer.count}poll-result-item-most{/if} js-poll-result-item"
|
||||
data-poll-item-count="{$aAnswer.count}"
|
||||
data-poll-item-pos="{$iPollItemsCount - $aAnswer@index - 1}">
|
||||
|
||||
<div class="poll-result-item-count">
|
||||
<strong>{$oTopic->getQuestionAnswerPercent($aAnswer@key)}%</strong>
|
||||
<span>({$aAnswer.count})</span>
|
||||
</div>
|
||||
|
||||
<div class="poll-result-item-chart">
|
||||
<div class="poll-result-item-label">{$aAnswer.text|escape}</div>
|
||||
<div class="poll-result-item-bar" style="width: {$oTopic->getQuestionAnswerPercent($aAnswer@key)}%;" ></div>
|
||||
</div>
|
||||
</li>
|
||||
{/foreach}
|
||||
</ul>
|
||||
|
||||
{* Кнопка сортировки *}
|
||||
<button class="button button-icon js-poll-result-button-sort" title="{$aLang.topic_question_vote_result_sort}"><i class="icon-align-left"></i></button>
|
||||
|
||||
<span class="poll-result-total">{$aLang.topic_question_vote_result}: {$oTopic->getQuestionCountVote()} | {$aLang.topic_question_abstain_result}: {$oTopic->getQuestionCountVoteAbstain()}</span>
|
|
@ -106,6 +106,13 @@
|
|||
{/if}
|
||||
{/block}
|
||||
|
||||
{* Опросы *}
|
||||
{block name='topic_content_polls'}
|
||||
{if ! $bTopicList}
|
||||
{include file='polls/poll.list.tpl' aPollItems=$oTopic->getPolls()}
|
||||
{/if}
|
||||
{/block}
|
||||
|
||||
{hook run='topic_content_end' topic=$oTopic bTopicList=$bTopicList}
|
||||
</div>
|
||||
{/block}
|
||||
|
|
|
@ -399,3 +399,87 @@ CREATE TABLE IF NOT EXISTS `prefix_storage` (
|
|||
|
||||
INSERT INTO `prefix_property_target` ( `type`, `date_create`, `date_update`, `state`, `params`) VALUES
|
||||
('topic_topic', '2014-01-31 12:01:34', NULL, 1, 'a:2:{s:6:"entity";s:23:"ModuleTopic_EntityTopic";s:4:"name";s:35:"Топик - Стандартный";}');
|
||||
|
||||
|
||||
-- 04.02.2014
|
||||
--
|
||||
-- Структура таблицы `prefix_poll`
|
||||
--
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `prefix_poll` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`user_id` int(11) NOT NULL,
|
||||
`target_type` varchar(50) NOT NULL,
|
||||
`target_id` int(11) DEFAULT NULL,
|
||||
`target_tmp` varchar(50) DEFAULT NULL,
|
||||
`title` varchar(500) NOT NULL,
|
||||
`count_answer_max` tinyint(4) NOT NULL DEFAULT '1',
|
||||
`count_vote` int(11) NOT NULL DEFAULT '0',
|
||||
`count_abstain` int(11) NOT NULL DEFAULT '0',
|
||||
`date_create` datetime NOT NULL,
|
||||
`date_end` datetime DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `user_id` (`user_id`),
|
||||
KEY `target_type_target_id` (`target_type`,`target_id`),
|
||||
KEY `target_tmp` (`target_tmp`),
|
||||
KEY `count_vote` (`count_vote`),
|
||||
KEY `count_abstain` (`count_abstain`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Структура таблицы `prefix_poll_answer`
|
||||
--
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `prefix_poll_answer` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`poll_id` int(11) NOT NULL,
|
||||
`title` varchar(500) CHARACTER SET utf8 NOT NULL,
|
||||
`count_vote` int(11) NOT NULL DEFAULT '0',
|
||||
`date_create` datetime NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `poll_id` (`poll_id`),
|
||||
KEY `count_vote` (`count_vote`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Структура таблицы `prefix_poll_vote`
|
||||
--
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `prefix_poll_vote` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`poll_id` int(11) NOT NULL,
|
||||
`answer_id` int(11) DEFAULT NULL,
|
||||
`user_id` int(11) NOT NULL,
|
||||
`date_create` datetime NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `poll_id` (`poll_id`),
|
||||
KEY `answer_id` (`answer_id`),
|
||||
KEY `user_id` (`user_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
--
|
||||
-- Ограничения внешнего ключа сохраненных таблиц
|
||||
--
|
||||
|
||||
--
|
||||
-- Ограничения внешнего ключа таблицы `prefix_poll_answer`
|
||||
--
|
||||
ALTER TABLE `prefix_poll_answer`
|
||||
ADD CONSTRAINT `prefix_poll_answer_ibfk_1` FOREIGN KEY (`poll_id`) REFERENCES `prefix_poll` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
--
|
||||
-- Ограничения внешнего ключа таблицы `prefix_poll_vote`
|
||||
--
|
||||
ALTER TABLE `prefix_poll_vote`
|
||||
ADD CONSTRAINT `prefix_poll_vote_ibfk_1` FOREIGN KEY (`poll_id`) REFERENCES `prefix_poll` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
ADD CONSTRAINT `prefix_poll_vote_ibfk_2` FOREIGN KEY (`answer_id`) REFERENCES `prefix_poll_answer` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
|
||||
-- 05.02.2014
|
||||
ALTER TABLE `prefix_poll_vote` DROP FOREIGN KEY `prefix_poll_vote_ibfk_2` ;
|
||||
ALTER TABLE `prefix_poll_vote` DROP `answer_id` ;
|
||||
ALTER TABLE `prefix_poll_vote` ADD `answers` VARCHAR( 500 ) NOT NULL AFTER `user_id` ;
|
Loading…
Reference in a new issue