1
0
Fork 0
mirror of https://github.com/Oreolek/ifhub.club.git synced 2024-06-16 23:00:51 +03:00

Переработка типов топиков, теперь типы можно создавать самому, удаление функционала старого фотосета

Обновление framework
Фикс комментариев
This commit is contained in:
Mzhelskiy Maxim 2014-01-11 23:27:27 +07:00
parent 7be442c269
commit 79610afc8b
48 changed files with 1072 additions and 3833 deletions

View file

@ -67,9 +67,6 @@ class ActionAjax extends Action {
$this->AddEventPreg('/^blogs$/i','/^get-by-category$/','EventBlogsGetByCategory');
$this->AddEventPreg('/^preview$/i','/^text$/','EventPreviewText');
$this->AddEventPreg('/^preview$/i','/^topic$/','EventPreviewTopic');
$this->AddEventPreg('/^upload$/i','/^image$/','EventUploadImage');
$this->AddEventPreg('/^autocompleter$/i','/^tag$/','EventAutocompleterTag');
$this->AddEventPreg('/^autocompleter$/i','/^user$/','EventAutocompleterUser');
@ -1299,73 +1296,6 @@ class ActionAjax extends Action {
return;
}
}
/**
* Предпросмотр топика
*
*/
protected function EventPreviewTopic() {
/**
* Т.к. используется обработка отправки формы, то устанавливаем тип ответа 'jsonIframe' (тот же JSON только обернутый в textarea)
* Это позволяет избежать ошибок в некоторых браузерах, например, Opera
*/
$this->Viewer_SetResponseAjax('jsonIframe',false);
/**
* Пользователь авторизован?
*/
if (!$this->oUserCurrent) {
$this->Message_AddErrorSingle($this->Lang_Get('need_authorization'),$this->Lang_Get('error'));
return;
}
/**
* Допустимый тип топика?
*/
if (!$this->Topic_IsAllowTopicType($sType=getRequestStr('topic_type'))) {
$this->Message_AddErrorSingle($this->Lang_Get('topic_create_type_error'),$this->Lang_Get('error'));
return;
}
/**
* Создаем объект топика для валидации данных
*/
$oTopic=Engine::GetEntity('ModuleTopic_EntityTopic');
$oTopic->_setValidateScenario($sType); // зависит от типа топика
$oTopic->setTitle(strip_tags(getRequestStr('topic_title')));
$oTopic->setTextSource(getRequestStr('topic_text'));
$oTopic->setTags(getRequestStr('topic_tags'));
$oTopic->setDateAdd(date("Y-m-d H:i:s"));
$oTopic->setUserId($this->oUserCurrent->getId());
$oTopic->setType($sType);
/**
* Валидируем необходимые поля топика
*/
$oTopic->_Validate(array('topic_title','topic_text','topic_tags','topic_type'),false);
if ($oTopic->_hasValidateErrors()) {
$this->Message_AddErrorSingle($oTopic->_getValidateError());
return false;
}
/**
* Формируем текст топика
*/
list($sTextShort,$sTextNew,$sTextCut) = $this->Text_Cut($oTopic->getTextSource());
$oTopic->setCutText($sTextCut);
$oTopic->setText($this->Text_Parser($sTextNew));
$oTopic->setTextShort($this->Text_Parser($sTextShort));
/**
* Рендерим шаблон для предпросмотра топика
*/
$oViewer=$this->Viewer_GetLocalViewer();
$oViewer->Assign('oTopic',$oTopic);
$sTemplate="topics/topic_preview_{$oTopic->getType()}.tpl";
if (!$this->Viewer_TemplateExists($sTemplate)) {
$sTemplate='topics/topic_preview_topic.tpl';
}
$sTextResult=$oViewer->Fetch($sTemplate);
/**
* Передаем результат в ajax ответ
*/
$this->Viewer_AssignAjax('sText',$sTextResult);
return true;
}
/**
* Предпросмотр текста
*
@ -1386,68 +1316,6 @@ class ActionAjax extends Action {
*/
$this->Viewer_AssignAjax('sText',$sTextResult);
}
/**
* Загрузка изображения
*
*/
protected function EventUploadImage() {
/**
* Т.к. используется обработка отправки формы, то устанавливаем тип ответа 'jsonIframe' (тот же JSON только обернутый в textarea)
* Это позволяет избежать ошибок в некоторых браузерах, например, Opera
*/
$this->Viewer_SetResponseAjax('jsonIframe',false);
/**
* Пользователь авторизован?
*/
if (!$this->oUserCurrent) {
$this->Message_AddErrorSingle($this->Lang_Get('need_authorization'),$this->Lang_Get('error'));
return;
}
$sFile=null;
/**
* Был выбран файл с компьютера и он успешно зугрузился?
*/
if (is_uploaded_file($_FILES['img_file']['tmp_name'])) {
if(!$sFile=$this->Topic_UploadTopicImageFile($_FILES['img_file'],$this->oUserCurrent)) {
$this->Message_AddErrorSingle($this->Lang_Get('uploadimg_file_error'),$this->Lang_Get('error'));
return;
}
} elseif (isPost('img_url') && $_REQUEST['img_url']!='' && $_REQUEST['img_url']!='http://') {
/**
* Загрузка файла по URl
*/
$sFile=$this->Topic_UploadTopicImageUrl($_REQUEST['img_url'],$this->oUserCurrent);
switch (true) {
case is_string($sFile):
break;
case ($sFile==ModuleImage::UPLOAD_IMAGE_ERROR_READ):
$this->Message_AddErrorSingle($this->Lang_Get('uploadimg_url_error_read'),$this->Lang_Get('error'));
return;
case ($sFile==ModuleImage::UPLOAD_IMAGE_ERROR_SIZE):
$this->Message_AddErrorSingle($this->Lang_Get('uploadimg_url_error_size'),$this->Lang_Get('error'));
return;
case ($sFile==ModuleImage::UPLOAD_IMAGE_ERROR_TYPE):
$this->Message_AddErrorSingle($this->Lang_Get('uploadimg_url_error_type'),$this->Lang_Get('error'));
return;
default:
case ($sFile==ModuleImage::UPLOAD_IMAGE_ERROR):
$this->Message_AddErrorSingle($this->Lang_Get('uploadimg_url_error'),$this->Lang_Get('error'));
return;
}
}
/**
* Если файл успешно загружен, формируем HTML вставки и возвращаем в ajax ответе
*/
if ($sFile) {
$sText=$this->Image_BuildHTML($sFile, $_REQUEST);
$this->Viewer_AssignAjax('sText',$sText);
}
}
/**
* Автоподставновка тегов
*

View file

@ -0,0 +1,535 @@
<?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
*
---------------------------------------------------------
*/
/**
* Экшен обработки УРЛа вида /content/ - управление своими топиками
*
* @package actions
* @since 1.0
*/
class ActionContent extends Action {
/**
* Главное меню
*
* @var string
*/
protected $sMenuHeadItemSelect='blog';
/**
* Меню
*
* @var string
*/
protected $sMenuItemSelect='topic';
/**
* СубМеню
*
* @var string
*/
protected $sMenuSubItemSelect='topic';
/**
* Текущий юзер
*
* @var ModuleUser_EntityUser|null
*/
protected $oUserCurrent=null;
/**
* Инициализация
*
*/
public function Init() {
/**
* Проверяем авторизован ли юзер
*/
if (!$this->User_IsAuthorization()) {
return parent::EventNotFound();
}
$this->oUserCurrent=$this->User_GetUserCurrent();
/**
* Усанавливаем дефолтный евент
*/
$this->SetDefaultEvent('add');
/**
* Устанавливаем title страницы
*/
$this->Viewer_AddHtmlTitle($this->Lang_Get('topic_title'));
}
/**
* Регистрируем евенты
*
*/
protected function RegisterEvent() {
$this->AddEventPreg('/^add$/i','/^[a-z_0-9]{1,50}$/i','/^$/i','EventAdd');
$this->AddEventPreg('/^edit$/i','/^\d{1,10}$/i','/^$/i','EventEdit');
$this->AddEventPreg('/^delete$/i','/^\d{1,10}$/i','/^$/i','EventDelete');
$this->AddEventPreg('/^published$/i','/^(page([1-9]\d{0,5}))?$/i','EventShowTopics');
$this->AddEventPreg('/^drafts$/i','/^(page([1-9]\d{0,5}))?$/i','EventShowTopics');
$this->AddEventPreg('/^ajax$/i','/^add$/i','/^$/i','EventAjaxAdd');
$this->AddEventPreg('/^ajax$/i','/^edit$/i','/^$/i','EventAjaxEdit');
$this->AddEventPreg('/^ajax$/i','/^preview$/i','/^$/i','EventAjaxPreview');
}
/**********************************************************************************
************************ РЕАЛИЗАЦИЯ ЭКШЕНА ***************************************
**********************************************************************************
*/
/**
* Выводит список топиков
*
*/
protected function EventShowTopics() {
/**
* Меню
*/
$this->sMenuSubItemSelect=$this->sCurrentEvent;
/**
* Передан ли номер страницы
*/
$iPage=$this->GetParamEventMatch(0,2) ? $this->GetParamEventMatch(0,2) : 1;
/**
* Получаем список топиков
*/
$aResult=$this->Topic_GetTopicsPersonalByUser($this->oUserCurrent->getId(),$this->sCurrentEvent=='published' ? 1 : 0,$iPage,Config::Get('module.topic.per_page'));
$aTopics=$aResult['collection'];
/**
* Формируем постраничность
*/
$aPaging=$this->Viewer_MakePaging($aResult['count'],$iPage,Config::Get('module.topic.per_page'),Config::Get('pagination.pages.count'),Router::GetPath('content').$this->sCurrentEvent);
/**
* Загружаем переменные в шаблон
*/
$this->Viewer_Assign('aPaging',$aPaging);
$this->Viewer_Assign('aTopics',$aTopics);
$this->Viewer_AddHtmlTitle($this->Lang_Get('topic_menu_'.$this->sCurrentEvent));
}
protected function EventDelete() {
$this->Security_ValidateSendForm();
/**
* Получаем номер топика из УРЛ и проверяем существует ли он
*/
$sTopicId=$this->GetParam(0);
if (!($oTopic=$this->Topic_GetTopicById($sTopicId))) {
return parent::EventNotFound();
}
/**
* проверяем есть ли право на удаление топика
*/
if (!$this->ACL_IsAllowDeleteTopic($oTopic,$this->oUserCurrent)) {
return parent::EventNotFound();
}
/**
* Удаляем топик
*/
$this->Hook_Run('topic_delete_before', array('oTopic'=>$oTopic));
$this->Topic_DeleteTopic($oTopic);
$this->Hook_Run('topic_delete_after', array('oTopic'=>$oTopic));
/**
* Перенаправляем на страницу со списком топиков из блога этого топика
*/
Router::Location($oTopic->getBlog()->getUrlFull());
}
protected function EventEdit() {
/**
* Получаем номер топика из УРЛ и проверяем существует ли он
*/
$sTopicId=$this->GetParam(0);
if (!($oTopic=$this->Topic_GetTopicById($sTopicId))) {
return parent::EventNotFound();
}
/**
* Проверяем тип топика
*/
if (!$this->Topic_IsAllowTopicType($oTopic->getType())) {
return parent::EventNotFound();
}
/**
* Если права на редактирование
*/
if (!$this->ACL_IsAllowEditTopic($oTopic,$this->oUserCurrent)) {
return parent::EventNotFound();
}
/**
* Вызов хуков
*/
$this->Hook_Run('topic_edit_show',array('oTopic'=>$oTopic));
/**
* Загружаем переменные в шаблон
*/
$this->Viewer_Assign('aBlogsAllow',$this->Blog_GetBlogsAllowByUser($this->oUserCurrent));
$this->Viewer_Assign('sTopicType',$oTopic->getType());
$this->Viewer_AddHtmlTitle($this->Lang_Get('topic_topic_edit'));
$this->Viewer_Assign('oTopicEdit', $oTopic);
$this->SetTemplateAction('add');
}
/**
* Добавление топика
*
*/
protected function EventAdd() {
$sTopicType=$this->GetParam(0);
if (!$this->Topic_IsAllowTopicType($sTopicType)) {
return parent::EventNotFound();
}
$this->sMenuSubItemSelect=$sTopicType;
/**
* Вызов хуков
*/
$this->Hook_Run('topic_add_show');
/**
* Загружаем переменные в шаблон
*/
$this->Viewer_Assign('sTopicType',$sTopicType);
$this->Viewer_Assign('aBlogsAllow',$this->Blog_GetBlogsAllowByUser($this->oUserCurrent));
$this->Viewer_AddHtmlTitle($this->Lang_Get('topic_topic_create'));
$this->SetTemplateAction('add');
}
protected function EventAjaxEdit() {
$this->Viewer_SetResponseAjax();
$aTopicRequest=getRequest('topic');
if (!(isset($aTopicRequest['id']) and $oTopic=$this->Topic_GetTopicById($aTopicRequest['id']))) {
$this->Message_AddErrorSingle($this->Lang_Get('system_error'));
return;
}
if (!$this->Topic_IsAllowTopicType($oTopic->getType())) {
$this->Message_AddErrorSingle($this->Lang_Get('system_error'));
return;
}
/**
* Проверяем разрешено ли постить топик по времени
*/
if (isPost('submit_topic_publish') and !$oTopic->getPublishDraft() and !$this->ACL_CanPostTopicTime($this->oUserCurrent)) {
$this->Message_AddErrorSingle($this->Lang_Get('topic_time_limit'),$this->Lang_Get('error'));
return;
}
/**
* Если права на редактирование
*/
if (!$this->ACL_IsAllowEditTopic($oTopic,$this->oUserCurrent)) {
$this->Message_AddErrorSingle($this->Lang_Get('system_error'));
return;
}
/**
* Сохраняем старое значение идентификатора блога
*/
$sBlogIdOld = $oTopic->getBlogId();
$oTopic->_setDataSafe(getRequest('topic'));
$oTopic->setProperties(getRequest('property'));
$oTopic->setUserIp(func_getIp());
/**
* Публикуем или сохраняем в черновиках
*/
$bSendNotify=false;
if (isset($_REQUEST['submit_topic_publish'])) {
$oTopic->setPublish(1);
if ($oTopic->getPublishDraft()==0) {
$oTopic->setPublishDraft(1);
$oTopic->setDateAdd(date("Y-m-d H:i:s"));
$bSendNotify=true;
}
} else {
$oTopic->setPublish(0);
}
/**
* Принудительный вывод на главную
*/
if ($this->ACL_IsAllowPublishIndex($this->oUserCurrent)) {
if (isset($_REQUEST['topic']['topic_publish_index'])) {
$oTopic->setPublishIndex(1);
} else {
$oTopic->setPublishIndex(0);
}
}
/**
* Запрет на комментарии к топику
*/
$oTopic->setForbidComment(0);
if (isset($_REQUEST['topic']['topic_forbid_comment'])) {
$oTopic->setForbidComment(1);
}
if ($oTopic->_Validate()) {
$oBlog=$oTopic->getBlog();
/**
* Проверяем права на постинг в блог
*/
if (!$this->ACL_IsAllowBlog($oBlog,$this->oUserCurrent)) {
$this->Message_AddErrorSingle($this->Lang_Get('topic_create_blog_error_noallow'),$this->Lang_Get('error'));
return false;
}
/**
* Получаемый и устанавливаем разрезанный текст по тегу <cut>
*/
list($sTextShort,$sTextNew,$sTextCut) = $this->Text_Cut($oTopic->getTextSource());
$oTopic->setCutText($sTextCut);
// TODO: передача параметров в Topic_Parser пока не используется - нужно заменить на этот вызов все места с парсингом топика
$oTopic->setText($this->Topic_Parser($sTextNew,$oTopic));
$oTopic->setTextShort($this->Topic_Parser($sTextShort,$oTopic));
/**
* Сохраняем топик
*/
if ($this->Topic_UpdateTopic($oTopic)) {
$this->Hook_Run('topic_edit_after', array('oTopic'=>$oTopic,'oBlog'=>$oBlog,'bSendNotify'=>&$bSendNotify));
/**
* Обновляем данные в комментариях, если топик был перенесен в новый блог
*/
if($sBlogIdOld!=$oTopic->getBlogId()) {
$this->Comment_UpdateTargetParentByTargetId($oTopic->getBlogId(), 'topic', $oTopic->getId());
$this->Comment_UpdateTargetParentByTargetIdOnline($oTopic->getBlogId(), 'topic', $oTopic->getId());
}
/**
* Обновляем количество топиков в блоге
*/
if ($sBlogIdOld!=$oTopic->getBlogId()) {
$this->Blog_RecalculateCountTopicByBlogId($sBlogIdOld);
}
$this->Blog_RecalculateCountTopicByBlogId($oTopic->getBlogId());
/**
* Добавляем событие в ленту
*/
$this->Stream_write($oTopic->getUserId(), 'add_topic', $oTopic->getId(),$oTopic->getPublish() && $oBlog->getType()!='close');
/**
* Рассылаем о новом топике подписчикам блога
*/
if ($bSendNotify) {
$this->Topic_SendNotifyTopicNew($oBlog,$oTopic,$oTopic->getUser());
}
if (!$oTopic->getPublish() and !$this->oUserCurrent->isAdministrator() and $this->oUserCurrent->getId()!=$oTopic->getUserId()) {
$sUrlRedirect=$oBlog->getUrlFull();
} else {
$sUrlRedirect=$oTopic->getUrl();
}
$this->Viewer_AssignAjax('sUrlRedirect',$sUrlRedirect);
$this->Message_AddNotice('Обновление прошло успешно',$this->Lang_Get('attention'));
} else {
$this->Message_AddErrorSingle($this->Lang_Get('system_error'));
}
} else {
$this->Message_AddError($oTopic->_getValidateError(),$this->Lang_Get('error'));
}
}
protected function EventAjaxAdd() {
$this->Viewer_SetResponseAjax();
/**
* TODO: Здесь нужна проверка прав на создание топика
*/
$sTopicType=getRequestStr('topic_type');
if (!$this->Topic_IsAllowTopicType($sTopicType)) {
$this->Message_AddErrorSingle($this->Lang_Get('system_error'));
return;
}
/**
* Проверяем разрешено ли постить топик по времени
*/
if (isPost('submit_topic_publish') and !$this->ACL_CanPostTopicTime($this->oUserCurrent)) {
$this->Message_AddErrorSingle($this->Lang_Get('topic_time_limit'),$this->Lang_Get('error'));
return;
}
/**
* Создаем топик
*/
$oTopic=Engine::GetEntity('Topic');
$oTopic->_setDataSafe(getRequest('topic'));
$oTopic->setProperties(getRequest('property'));
$oTopic->setUserId($this->oUserCurrent->getId());
$oTopic->setDateAdd(date("Y-m-d H:i:s"));
$oTopic->setUserIp(func_getIp());
$oTopic->setTopicType($sTopicType);
/**
* Публикуем или сохраняем
*/
if (isset($_REQUEST['submit_topic_publish'])) {
$oTopic->setPublish(1);
$oTopic->setPublishDraft(1);
} else {
$oTopic->setPublish(0);
$oTopic->setPublishDraft(0);
}
/**
* Принудительный вывод на главную
*/
$oTopic->setPublishIndex(0);
if ($this->ACL_IsAllowPublishIndex($this->oUserCurrent)) {
if (isset($_REQUEST['topic']['topic_publish_index'])) {
$oTopic->setPublishIndex(1);
}
}
/**
* Запрет на комментарии к топику
*/
$oTopic->setForbidComment(0);
if (isset($_REQUEST['topic']['topic_forbid_comment'])) {
$oTopic->setForbidComment(1);
}
if ($oTopic->_Validate()) {
$oBlog=$oTopic->getBlog();
/**
* Проверяем права на постинг в блог
*/
if (!$this->ACL_IsAllowBlog($oBlog,$this->oUserCurrent)) {
$this->Message_AddErrorSingle($this->Lang_Get('topic_create_blog_error_noallow'),$this->Lang_Get('error'));
return false;
}
/**
* Получаем и устанавливаем разрезанный текст по тегу <cut>
*/
list($sTextShort,$sTextNew,$sTextCut) = $this->Text_Cut($oTopic->getTextSource());
$oTopic->setCutText($sTextCut);
$oTopic->setText($this->Topic_Parser($sTextNew,$oTopic));
$oTopic->setTextShort($this->Topic_Parser($sTextShort,$oTopic));
if ($this->Topic_AddTopic($oTopic)) {
$this->Hook_Run('topic_add_after', array('oTopic'=>$oTopic,'oBlog'=>$oBlog));
/**
* Получаем топик, чтоб подцепить связанные данные
*/
$oTopic=$this->Topic_GetTopicById($oTopic->getId());
/**
* Обновляем количество топиков в блоге
*/
$this->Blog_RecalculateCountTopicByBlogId($oTopic->getBlogId());
/**
* Фиксируем ID у media файлов топика
*/
if (isset($_COOKIE['media_target_tmp_topic']) and is_string($_COOKIE['media_target_tmp_topic'])) {
$aTargetItems=$this->Media_GetTargetItemsByTargetTmpAndTargetType($_COOKIE['media_target_tmp_topic'],'topic');
foreach($aTargetItems as $oTarget) {
$oTarget->setTargetTmp(null);
$oTarget->setTargetId($oTopic->getId());
$oTarget->Update();
}
}
setcookie('media_target_tmp_topic',null);
/**
* Добавляем автора топика в подписчики на новые комментарии к этому топику
*/
$oUser=$oTopic->getUser();
if ($oUser) {
$this->Subscribe_AddSubscribeSimple('topic_new_comment',$oTopic->getId(),$oUser->getMail(),$oUser->getId());
}
/**
* Делаем рассылку спама всем, кто состоит в этом блоге
*/
if ($oTopic->getPublish()==1 and $oBlog->getType()!='personal') {
$this->Topic_SendNotifyTopicNew($oBlog,$oTopic,$oUser);
}
/**
* Добавляем событие в ленту
*/
$this->Stream_write($oTopic->getUserId(), 'add_topic', $oTopic->getId(),$oTopic->getPublish() && $oBlog->getType()!='close');
$this->Viewer_AssignAjax('sUrlRedirect',$oTopic->getUrl());
$this->Message_AddNotice('Добавление прошло успешно',$this->Lang_Get('attention'));
} else {
$this->Message_AddError('Возникла ошибка при добавлении',$this->Lang_Get('error'));
}
} else {
$this->Message_AddError($oTopic->_getValidateError(),$this->Lang_Get('error'));
}
}
public function EventAjaxPreview() {
/**
* Т.к. используется обработка отправки формы, то устанавливаем тип ответа 'jsonIframe' (тот же JSON только обернутый в textarea)
* Это позволяет избежать ошибок в некоторых браузерах, например, Opera
*/
$this->Viewer_SetResponseAjax('jsonIframe',false);
/**
* Пользователь авторизован?
*/
if (!$this->oUserCurrent) {
$this->Message_AddErrorSingle($this->Lang_Get('need_authorization'),$this->Lang_Get('error'));
return;
}
/**
* Допустимый тип топика?
*/
if (!$this->Topic_IsAllowTopicType($sType=getRequestStr('topic_type'))) {
$this->Message_AddErrorSingle($this->Lang_Get('topic_create_type_error'),$this->Lang_Get('error'));
return;
}
/**
* Создаем объект топика для валидации данных
*/
$oTopic=Engine::GetEntity('ModuleTopic_EntityTopic');
$aTopicRequest=getRequest('topic');
$oTopic->setTitle(isset($aTopicRequest['topic_title']) ? strip_tags($aTopicRequest['topic_title']) : '');
$oTopic->setTextSource(isset($aTopicRequest['topic_text_source']) ? $aTopicRequest['topic_text_source'] : '');
$oTopic->setTags(isset($aTopicRequest['topic_tags']) ? $aTopicRequest['topic_tags'] : '');
$oTopic->setDateAdd(date("Y-m-d H:i:s"));
$oTopic->setUserId($this->oUserCurrent->getId());
$oTopic->setType($sType);
/**
* Валидируем необходимые поля топика
*/
$oTopic->_Validate(array('topic_title','topic_text','topic_tags','topic_type'),false);
if ($oTopic->_hasValidateErrors()) {
$this->Message_AddErrorSingle($oTopic->_getValidateError());
return false;
}
/**
* Формируем текст топика
*/
list($sTextShort,$sTextNew,$sTextCut) = $this->Text_Cut($oTopic->getTextSource());
$oTopic->setCutText($sTextCut);
$oTopic->setText($this->Topic_Parser($sTextNew,$oTopic));
$oTopic->setTextShort($this->Topic_Parser($sTextShort,$oTopic));
/**
* Рендерим шаблон для предпросмотра топика
*/
$oViewer=$this->Viewer_GetLocalViewer();
$oViewer->Assign('oTopic',$oTopic);
$sTemplate="topics/topic_preview_{$oTopic->getType()}.tpl";
if (!$this->Viewer_TemplateExists($sTemplate)) {
$sTemplate='topics/topic_preview.tpl';
}
$sTextResult=$oViewer->Fetch($sTemplate);
/**
* Передаем результат в ajax ответ
*/
$this->Viewer_AssignAjax('sText',$sTextResult);
return true;
}
/**
* При завершении экшена загружаем необходимые переменные
*
*/
public function EventShutdown() {
$this->Viewer_Assign('sMenuHeadItemSelect',$this->sMenuHeadItemSelect);
$this->Viewer_Assign('sMenuItemSelect',$this->sMenuItemSelect);
$this->Viewer_Assign('sMenuSubItemSelect',$this->sMenuSubItemSelect);
}
}
?>

View file

@ -1,513 +0,0 @@
<?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
*
---------------------------------------------------------
*/
/**
* Экшен обработки УРЛа вида /link/ - управление своими топиками(тип: ссылка)
*
* @package actions
* @since 1.0
*/
class ActionLink extends Action {
/**
* Главное меню
*
* @var string
*/
protected $sMenuHeadItemSelect='blog';
/**
* Меню
*
* @var string
*/
protected $sMenuItemSelect='topic';
/**
* СубМеню
*
* @var string
*/
protected $sMenuSubItemSelect='link';
/**
* Текущий юзер
*
* @var ModuleUser_EntityUser|null
*/
protected $oUserCurrent=null;
/**
* Тип топика
*
* @var string
*/
protected $sType = 'link';
/**
* Инициализация
*
*/
public function Init() {
/**
* Получаем текущего пользователя
*/
$this->oUserCurrent=$this->User_GetUserCurrent();
/**
* Устанавливаем дефолтный евент
*/
$this->SetDefaultEvent('add');
/**
* Устанавливаем title страницы
*/
$this->Viewer_AddHtmlTitle($this->Lang_Get('topic_link_title'));
}
/**
* Регистрируем евенты
*
*/
protected function RegisterEvent() {
$this->AddEvent('add','EventAdd');
$this->AddEvent('edit','EventEdit');
$this->AddEvent('go','EventGo');
}
/**********************************************************************************
************************ РЕАЛИЗАЦИЯ ЭКШЕНА ***************************************
**********************************************************************************
*/
/**
* Переход по ссылке с подсчетом количества переходов
*
*/
protected function EventGo() {
/**
* Получаем номер топика из УРЛ и проверяем существует ли он
*/
$sTopicId=$this->GetParam(0);
if (!($oTopic=$this->Topic_GetTopicById($sTopicId)) or !$oTopic->getPublish()) {
return parent::EventNotFound();
}
/**
* проверяем является ли топик ссылкой
*/
if ($oTopic->getType()!=$this->sType) {
return parent::EventNotFound();
}
/**
* увелививаем число переходов по ссылке
*/
$oTopic->setLinkCountJump($oTopic->getLinkCountJump()+1);
$this->Topic_UpdateTopic($oTopic);
/**
* собственно сам переход по ссылке
*/
Router::Location($oTopic->getLinkUrl());
}
/**
* Редактирование топика-ссылки
*
*/
protected function EventEdit() {
/**
* Проверяем авторизован ли юзер
*/
if (!$this->User_IsAuthorization()) {
$this->Message_AddErrorSingle($this->Lang_Get('not_access'),$this->Lang_Get('error'));
return Router::Action('error');
}
/**
* Получаем номер топика из УРЛ и проверяем существует ли он
*/
$sTopicId=$this->GetParam(0);
if (!($oTopic=$this->Topic_GetTopicById($sTopicId))) {
return parent::EventNotFound();
}
/**
* Проверяем тип топика
*/
if ($oTopic->getType()!=$this->sType) {
return parent::EventNotFound();
}
/**
* Если права на редактирование
*/
if (!$this->ACL_IsAllowEditTopic($oTopic,$this->oUserCurrent)) {
return parent::EventNotFound();
}
/**
* Вызов хуков
*/
$this->Hook_Run('topic_edit_show',array('oTopic'=>$oTopic));
/**
* Загружаем переменные в шаблон
*/
$this->Viewer_Assign('aBlogsAllow',$this->Blog_GetBlogsAllowByUser($this->oUserCurrent));
$this->Viewer_Assign('sTopicType', $this->sType);
$this->Viewer_AddHtmlTitle($this->Lang_Get('topic_link_title_edit'));
/**
* Устанавливаем шаблон вывода
*/
$this->SetTemplateAction('add');
/**
* Проверяем отправлена ли форма с данными(хотяб одна кнопка)
*/
if (isset($_REQUEST['submit_topic_publish']) or isset($_REQUEST['submit_topic_save'])) {
/**
* Обрабатываем отправку формы
*/
return $this->SubmitEdit($oTopic);
} else {
/**
* Заполняем поля формы для редактирования
* Только перед отправкой формы!
*/
$_REQUEST['topic_title']=$oTopic->getTitle();
$_REQUEST['topic_link_url']=$oTopic->getLinkUrl();
$_REQUEST['topic_text']=$oTopic->getTextSource();
$_REQUEST['topic_tags']=$oTopic->getTags();
$_REQUEST['blog_id']=$oTopic->getBlogId();
$_REQUEST['topic_id']=$oTopic->getId();
$_REQUEST['topic_publish_index']=$oTopic->getPublishIndex();
$_REQUEST['topic_forbid_comment']=$oTopic->getForbidComment();
}
$this->Viewer_Assign('oTopicEdit', $oTopic);
}
/**
* Добавление топика-ссылки
*
*/
protected function EventAdd() {
/**
* Проверяем авторизован ли юзер
*/
if (!$this->User_IsAuthorization()) {
$this->Message_AddErrorSingle($this->Lang_Get('not_access'),$this->Lang_Get('error'));
return Router::Action('error');
}
/**
* Вызов хуков
*/
$this->Hook_Run('topic_add_show');
/**
* Загружаем переменные в шаблон
*/
$this->Viewer_Assign('aBlogsAllow',$this->Blog_GetBlogsAllowByUser($this->oUserCurrent));
$this->Viewer_Assign('sTopicType', $this->sType);
$this->Viewer_AddHtmlTitle($this->Lang_Get('topic_link_title_create'));
/**
* Обрабатываем отправку формы
*/
return $this->SubmitAdd();
}
/**
* Обработка добавлени топика
*
* @return mixed
*/
protected function SubmitAdd() {
/**
* Проверяем отправлена ли форма с данными(хотяб одна кнопка)
*/
if (!isPost('submit_topic_publish') and !isPost('submit_topic_save')) {
return false;
}
$oTopic=Engine::GetEntity('Topic');
$oTopic->_setValidateScenario($this->sType);
/**
* Заполняем поля для валидации
*/
$oTopic->setBlogId(getRequestStr('blog_id'));
$oTopic->setTitle(strip_tags(getRequestStr('topic_title')));
$oTopic->setTextSource(getRequestStr('topic_text'));
$oTopic->setTags(getRequestStr('topic_tags'));
$oTopic->setUserId($this->oUserCurrent->getId());
$oTopic->setType($this->sType);
$oTopic->setLinkUrl(getRequestStr('topic_link_url'));
$oTopic->setDateAdd(date("Y-m-d H:i:s"));
$oTopic->setUserIp(func_getIp());
/**
* Проверка корректности полей формы
*/
if (!$this->checkTopicFields($oTopic)) {
return false;
}
/**
* Определяем в какой блог делаем запись
*/
$iBlogId=$oTopic->getBlogId();
if ($iBlogId==0) {
$oBlog=$this->Blog_GetPersonalBlogByUserId($this->oUserCurrent->getId());
} else {
$oBlog=$this->Blog_GetBlogById($iBlogId);
}
/**
* Если блог не определен выдаем предупреждение
*/
if (!$oBlog) {
$this->Message_AddErrorSingle($this->Lang_Get('topic_create_blog_error_unknown'),$this->Lang_Get('error'));
return false;
}
/**
* Проверяем права на постинг в блог
*/
if (!$this->ACL_IsAllowBlog($oBlog,$this->oUserCurrent)) {
$this->Message_AddErrorSingle($this->Lang_Get('topic_create_blog_error_noallow'),$this->Lang_Get('error'));
return false;
}
/**
* Проверяем разрешено ли постить топик по времени
*/
if (isPost('submit_topic_publish') and !$this->ACL_CanPostTopicTime($this->oUserCurrent)) {
$this->Message_AddErrorSingle($this->Lang_Get('topic_time_limit'),$this->Lang_Get('error'));
return;
}
/**
* Теперь можно смело добавлять топик к блогу
*/
$oTopic->setBlogId($oBlog->getId());
$oTopic->setText($this->Text_Parser($oTopic->getTextSource()));
$oTopic->setTextShort($oTopic->getText());
$oTopic->setCutText(null);
/**
* Публикуем или сохраняем
*/
if (isset($_REQUEST['submit_topic_publish'])) {
$oTopic->setPublish(1);
$oTopic->setPublishDraft(1);
} else {
$oTopic->setPublish(0);
$oTopic->setPublishDraft(0);
}
/**
* Принудительный вывод на главную
*/
$oTopic->setPublishIndex(0);
if ($this->ACL_IsAllowPublishIndex($this->oUserCurrent)) {
if (getRequest('topic_publish_index')) {
$oTopic->setPublishIndex(1);
}
}
/**
* Запрет на комментарии к топику
*/
$oTopic->setForbidComment(0);
if (getRequest('topic_forbid_comment')) {
$oTopic->setForbidComment(1);
}
/**
* Запускаем выполнение хуков
*/
$this->Hook_Run('topic_add_before', array('oTopic'=>$oTopic,'oBlog'=>$oBlog));
/**
* Добавляем топик
*/
if ($this->Topic_AddTopic($oTopic)) {
$this->Hook_Run('topic_add_after', array('oTopic'=>$oTopic,'oBlog'=>$oBlog));
/**
* Получаем топик, чтоб подцепить связанные данные
*/
$oTopic=$this->Topic_GetTopicById($oTopic->getId());
/**
* Обновляем количество топиков в блоге
*/
$this->Blog_RecalculateCountTopicByBlogId($oTopic->getBlogId());
/**
* Добавляем автора топика в подписчики на новые комментарии к этому топику
*/
$oUser=$oTopic->getUser();
if ($oUser) {
$this->Subscribe_AddSubscribeSimple('topic_new_comment',$oTopic->getId(),$oUser->getMail(),$oUser->getId());
}
/**
* Делаем рассылку спама всем, кто состоит в этом блоге
*/
if ($oTopic->getPublish()==1 and $oBlog->getType()!='personal') {
$this->Topic_SendNotifyTopicNew($oBlog,$oTopic,$oUser);
}
/**
* Добавляем событие в ленту
*/
$this->Stream_write($oTopic->getUserId(), 'add_topic', $oTopic->getId(),$oTopic->getPublish() && $oBlog->getType()!='close');
Router::Location($oTopic->getUrl());
} else {
$this->Message_AddErrorSingle($this->Lang_Get('system_error'));
return Router::Action('error');
}
}
/**
* Обработка редактирования топика
*
* @param ModuleTopic_EntityTopic $oTopic
* @return mixed
*/
protected function SubmitEdit($oTopic) {
$oTopic->_setValidateScenario('link');
/**
* Сохраняем старое значение идентификатора блога
*/
$sBlogIdOld = $oTopic->getBlogId();
/**
* Заполняем поля для валидации
*/
$oTopic->setBlogId(getRequestStr('blog_id'));
$oTopic->setTitle(strip_tags(getRequestStr('topic_title')));
$oTopic->setLinkUrl(getRequestStr('topic_link_url'));
$oTopic->setTextSource(getRequestStr('topic_text'));
$oTopic->setTags(getRequestStr('topic_tags'));
$oTopic->setUserIp(func_getIp());
/**
* Проверка корректности полей формы
*/
if (!$this->checkTopicFields($oTopic)) {
return false;
}
/**
* Определяем в какой блог делаем запись
*/
$iBlogId=$oTopic->getBlogId();
if ($iBlogId==0) {
$oBlog=$this->Blog_GetPersonalBlogByUserId($oTopic->getUserId());
} else {
$oBlog=$this->Blog_GetBlogById($iBlogId);
}
/**
* Если блог не определен выдаем предупреждение
*/
if (!$oBlog) {
$this->Message_AddErrorSingle($this->Lang_Get('topic_create_blog_error_unknown'),$this->Lang_Get('error'));
return false;
}
/**
* Проверяем права на постинг в блог
*/
if (!$this->ACL_IsAllowBlog($oBlog,$this->oUserCurrent)) {
$this->Message_AddErrorSingle($this->Lang_Get('topic_create_blog_error_noallow'),$this->Lang_Get('error'));
return false;
}
/**
* Проверяем разрешено ли постить топик по времени
*/
if (isPost('submit_topic_publish') and !$oTopic->getPublishDraft() and !$this->ACL_CanPostTopicTime($this->oUserCurrent)) {
$this->Message_AddErrorSingle($this->Lang_Get('topic_time_limit'),$this->Lang_Get('error'));
return;
}
/**
* Теперь можно смело редактировать топик
*/
$oTopic->setBlogId($oBlog->getId());
$oTopic->setText($this->Text_Parser($oTopic->getTextSource()));
$oTopic->setTextShort($oTopic->getText());
/**
* Публикуем или сохраняем в черновиках
*/
$bSendNotify=false;
if (isset($_REQUEST['submit_topic_publish'])) {
$oTopic->setPublish(1);
if ($oTopic->getPublishDraft()==0) {
$oTopic->setPublishDraft(1);
$oTopic->setDateAdd(date("Y-m-d H:i:s"));
$bSendNotify=true;
}
} else {
$oTopic->setPublish(0);
}
/**
* Принудительный вывод на главную
*/
if ($this->ACL_IsAllowPublishIndex($this->oUserCurrent)) {
if (getRequest('topic_publish_index')) {
$oTopic->setPublishIndex(1);
} else {
$oTopic->setPublishIndex(0);
}
}
/**
* Запрет на комментарии к топику
*/
$oTopic->setForbidComment(0);
if (getRequest('topic_forbid_comment')) {
$oTopic->setForbidComment(1);
}
$this->Hook_Run('topic_edit_before', array('oTopic'=>$oTopic,'oBlog'=>$oBlog));
/**
* Сохраняем топик
*/
if ($this->Topic_UpdateTopic($oTopic)) {
$this->Hook_Run('topic_edit_after', array('oTopic'=>$oTopic,'oBlog'=>$oBlog,'bSendNotify'=>&$bSendNotify));
/**
* Обновляем данные в комментариях, если топик был перенесен в новый блог
*/
if($sBlogIdOld!=$oTopic->getBlogId()) {
$this->Comment_UpdateTargetParentByTargetId($oTopic->getBlogId(), 'topic', $oTopic->getId());
$this->Comment_UpdateTargetParentByTargetIdOnline($oTopic->getBlogId(), 'topic', $oTopic->getId());
}
/**
* Обновляем количество топиков в блоге
*/
if ($sBlogIdOld!=$oTopic->getBlogId()) {
$this->Blog_RecalculateCountTopicByBlogId($sBlogIdOld);
}
$this->Blog_RecalculateCountTopicByBlogId($oTopic->getBlogId());
/**
* Добавляем событие в ленту
*/
$this->Stream_write($oTopic->getUserId(), 'add_topic', $oTopic->getId(),$oTopic->getPublish() && $oBlog->getType()!='close');
/**
* Рассылаем о новом топике подписчикам блога
*/
if ($bSendNotify) {
$this->Topic_SendNotifyTopicNew($oBlog,$oTopic,$oTopic->getUser());
}
if (!$oTopic->getPublish() and !$this->oUserCurrent->isAdministrator() and $this->oUserCurrent->getId()!=$oTopic->getUserId()) {
Router::Location($oBlog->getUrlFull());
}
Router::Location($oTopic->getUrl());
} else {
$this->Message_AddErrorSingle($this->Lang_Get('system_error'));
return Router::Action('error');
}
}
/**
* Проверка полей формы
*
* @param ModuleTopic_EntityTopic $oTopic
* @return bool
*/
protected function checkTopicFields($oTopic) {
$this->Security_ValidateSendForm();
$bOk=true;
if (!$oTopic->_Validate()) {
$this->Message_AddError($oTopic->_getValidateError(),$this->Lang_Get('error'));
$bOk=false;
}
/**
* Выполнение хуков
*/
$this->Hook_Run('check_link_fields', array('bOk'=>&$bOk));
return $bOk;
}
/**
* При завершении экшена загружаем необходимые переменные
*
*/
public function EventShutdown() {
$this->Viewer_Assign('sMenuHeadItemSelect',$this->sMenuHeadItemSelect);
$this->Viewer_Assign('sMenuItemSelect',$this->sMenuItemSelect);
$this->Viewer_Assign('sMenuSubItemSelect',$this->sMenuSubItemSelect);
}
}
?>

View file

@ -1,778 +0,0 @@
<?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
*
---------------------------------------------------------
*/
/**
* Обработка УРЛа вида /photoset/ - управление своими топиками(тип: фотосет)
*
* @package actions
* @since 1.0
*/
class ActionPhotoset extends Action {
/**
* Главное меню
*
* @var string
*/
protected $sMenuHeadItemSelect='blog';
/**
* Меню
*
* @var string
*/
protected $sMenuItemSelect='topic';
/**
* СубМеню
*
* @var string
*/
protected $sMenuSubItemSelect='photoset';
/**
* Текущий юзер
*
* @var ModuleUser_EntityUser|null
*/
protected $oUserCurrent=null;
/**
* Тип топика
*
* @var string
*/
protected $sType = 'photoset';
/**
* Инициализация
*
*/
public function Init() {
/**
* Проверяем авторизован ли юзер
*/
$this->oUserCurrent=$this->User_GetUserCurrent();
$this->SetDefaultEvent('add');
$this->Viewer_AddHtmlTitle($this->Lang_Get('topic_photoset_title'));
/**
* Загружаем в шаблон JS текстовки
*/
$this->Lang_AddLangJs(array(
'topic_photoset_photo_delete','topic_photoset_mark_as_preview','topic_photoset_photo_delete_confirm',
'topic_photoset_is_preview','topic_photoset_upload_choose'
));
}
/**
* Регистрируем евенты
*
*/
protected function RegisterEvent() {
$this->AddEvent('add','EventAdd'); // Добавление топика
$this->AddEvent('edit','EventEdit'); // Редактирование топика
$this->AddEvent('deleteimage','EventDeletePhoto'); // Удаление изображения
$this->AddEvent('upload','EventUpload'); // Загрузка изображения
$this->AddEvent('getMore','EventGetMore'); // Загрузка изображения на сервер
$this->AddEvent('setimagedescription','EventSetPhotoDescription'); // Установка описания к фото
}
/**********************************************************************************
************************ РЕАЛИЗАЦИЯ ЭКШЕНА ***************************************
**********************************************************************************
*/
/**
* AJAX подгрузка следующих фото
*
*/
protected function EventGetMore() {
/**
* Устанавливаем формат Ajax ответа
*/
$this->Viewer_SetResponseAjax('json');
/**
* Существует ли топик
*/
$oTopic = $this->Topic_getTopicById(getRequestStr('topic_id'));
if (!$oTopic || !getRequest('last_id')) {
$this->Message_AddError($this->Lang_Get('system_error'), $this->Lang_Get('error'));
return false;
}
/**
* Получаем список фото
*/
$aPhotos = $oTopic->getPhotosetPhotos(getRequestStr('last_id'), Config::Get('module.topic.photoset.per_page'));
$aResult = array();
if (count($aPhotos)) {
/**
* Формируем данные для ajax ответа
*/
foreach($aPhotos as $oPhoto) {
$aResult[] = array('id' => $oPhoto->getId(), 'path_thumb' => $oPhoto->getWebPath('50crop'), 'path' => $oPhoto->getWebPath(), 'description' => $oPhoto->getDescription());
}
$this->Viewer_AssignAjax('photos', $aResult);
}
$this->Viewer_AssignAjax('bHaveNext', count($aPhotos)==Config::Get('module.topic.photoset.per_page'));
}
/**
* AJAX удаление фото
*
*/
protected function EventDeletePhoto() {
/**
* Устанавливаем формат Ajax ответа
*/
$this->Viewer_SetResponseAjax('json');
/**
* Проверяем авторизован ли юзер
*/
if (!$this->User_IsAuthorization()) {
$this->Message_AddErrorSingle($this->Lang_Get('not_access'),$this->Lang_Get('error'));
return Router::Action('error');
}
/**
* Поиск фото по id
*/
$oPhoto = $this->Topic_getTopicPhotoById(getRequestStr('id'));
if ($oPhoto) {
if ($oPhoto->getTopicId()) {
/**
* Проверяем права на топик
*/
if ($oTopic=$this->Topic_GetTopicById($oPhoto->getTopicId()) and $this->ACL_IsAllowEditTopic($oTopic,$this->oUserCurrent)) {
if ($oTopic->getPhotosetCount()>1) {
$this->Topic_deleteTopicPhoto($oPhoto);
/**
* Если удаляем главную фотку топика, то её необходимо сменить
*/
if ($oPhoto->getId()==$oTopic->getPhotosetMainPhotoId()) {
$aPhotos = $oTopic->getPhotosetPhotos(0,1);
$oTopic->setPhotosetMainPhotoId($aPhotos[0]->getId());
}
$oTopic->setPhotosetCount($oTopic->getPhotosetCount()-1);
$this->Topic_UpdateTopic($oTopic);
$this->Message_AddNotice($this->Lang_Get('topic_photoset_photo_deleted'), $this->Lang_Get('attention'));
} else {
$this->Message_AddError($this->Lang_Get('topic_photoset_photo_deleted_error_last'), $this->Lang_Get('error'));
}
return;
}
} else {
$this->Topic_deleteTopicPhoto($oPhoto);
$this->Message_AddNotice($this->Lang_Get('topic_photoset_photo_deleted'), $this->Lang_Get('attention'));
return;
}
}
$this->Message_AddError($this->Lang_Get('system_error'), $this->Lang_Get('error'));
}
/**
* AJAX установка описания фото
*
*/
protected function EventSetPhotoDescription() {
/**
* Устанавливаем формат Ajax ответа
*/
$this->Viewer_SetResponseAjax('json');
/**
* Проверяем авторизован ли юзер
*/
if (!$this->User_IsAuthorization()) {
$this->Message_AddErrorSingle($this->Lang_Get('not_access'),$this->Lang_Get('error'));
return Router::Action('error');
}
/**
* Поиск фото по id
*/
$oPhoto = $this->Topic_getTopicPhotoById(getRequestStr('id'));
if ($oPhoto) {
if ($oPhoto->getTopicId()) {
// проверяем права на топик
if ($oTopic=$this->Topic_GetTopicById($oPhoto->getTopicId()) and $this->ACL_IsAllowEditTopic($oTopic,$this->oUserCurrent)) {
$oPhoto->setDescription(htmlspecialchars(strip_tags(getRequestStr('text'))));
$this->Topic_updateTopicPhoto($oPhoto);
}
} else {
$oPhoto->setDescription(htmlspecialchars(strip_tags(getRequestStr('text'))));
$this->Topic_updateTopicPhoto($oPhoto);
}
}
}
/**
* AJAX загрузка фоток
*
* @return unknown
*/
protected function EventUpload() {
/**
* Устанавливаем формат Ajax ответа
* В зависимости от типа загрузчика устанавливается тип ответа
*/
if (getRequest('is_iframe')) {
$this->Viewer_SetResponseAjax('jsonIframe', false);
} else {
$this->Viewer_SetResponseAjax('json');
}
/**
* Проверяем авторизован ли юзер
*/
if (!$this->User_IsAuthorization()) {
$this->Message_AddErrorSingle($this->Lang_Get('not_access'),$this->Lang_Get('error'));
return Router::Action('error');
}
/**
* Файл был загружен?
*/
if (!isset($_FILES['Filedata']['tmp_name'])) {
$this->Message_AddError($this->Lang_Get('system_error'), $this->Lang_Get('error'));
return false;
}
$iTopicId = getRequestStr('topic_id');
$sTargetId = null;
$iCountPhotos = 0;
// Если от сервера не пришёл id топика, то пытаемся определить временный код для нового топика. Если и его нет. то это ошибка
if (!$iTopicId) {
$sTargetId = empty($_COOKIE['ls_photoset_target_tmp']) ? getRequestStr('ls_photoset_target_tmp') : $_COOKIE['ls_photoset_target_tmp'];
if (!is_string($sTargetId) or !$sTargetId) {
$this->Message_AddError($this->Lang_Get('system_error'), $this->Lang_Get('error'));
return false;
}
$iCountPhotos = $this->Topic_getCountPhotosByTargetTmp($sTargetId);
} else {
/**
* Загрузка фото к уже существующему топику
*/
$oTopic = $this->Topic_getTopicById($iTopicId);
if (!$oTopic or !$this->ACL_IsAllowEditTopic($oTopic,$this->oUserCurrent)) {
$this->Message_AddError($this->Lang_Get('system_error'), $this->Lang_Get('error'));
return false;
}
$iCountPhotos = $this->Topic_getCountPhotosByTopicId($iTopicId);
}
/**
* Максимальное количество фото в топике
*/
if ($iCountPhotos >= Config::Get('module.topic.photoset.count_photos_max')) {
$this->Message_AddError($this->Lang_Get('topic_photoset_error_too_much_photos', array('MAX' => Config::Get('module.topic.photoset.count_photos_max'))), $this->Lang_Get('error'));
return false;
}
/**
* Максимальный размер фото
*/
if ($_FILES['Filedata']['size'] > Config::Get('module.topic.photoset.photo_max_size')*1024) {
$this->Message_AddError($this->Lang_Get('topic_photoset_error_bad_filesize', array('MAX' => Config::Get('module.topic.photoset.photo_max_size'))), $this->Lang_Get('error'));
return false;
}
/**
* Загружаем файл
*/
$sFile = $this->Topic_UploadTopicPhoto($_FILES['Filedata']);
if ($sFile) {
/**
* Создаем фото
*/
$oPhoto = Engine::GetEntity('Topic_TopicPhoto');
$oPhoto->setPath($sFile);
if ($iTopicId) {
$oPhoto->setTopicId($iTopicId);
} else {
$oPhoto->setTargetTmp($sTargetId);
}
if ($oPhoto = $this->Topic_addTopicPhoto($oPhoto)) {
/**
* Если топик уже существует (редактирование), то обновляем число фоток в нём
*/
if (isset($oTopic)) {
$oTopic->setPhotosetCount($oTopic->getPhotosetCount()+1);
$this->Topic_UpdateTopic($oTopic);
}
$this->Viewer_AssignAjax('file', $oPhoto->getWebPath('100crop'));
$this->Viewer_AssignAjax('id', $oPhoto->getId());
$this->Message_AddNotice($this->Lang_Get('topic_photoset_photo_added'), $this->Lang_Get('attention'));
} else {
$this->Message_AddError($this->Lang_Get('system_error'), $this->Lang_Get('error'));
}
} else {
$this->Message_AddError($this->Lang_Get('system_error'), $this->Lang_Get('error'));
}
}
/**
* Редактирование топика
*
*/
protected function EventEdit() {
/**
* Проверяем авторизован ли юзер
*/
if (!$this->User_IsAuthorization()) {
$this->Message_AddErrorSingle($this->Lang_Get('not_access'),$this->Lang_Get('error'));
return Router::Action('error');
}
/**
* Получаем номер топика из УРЛ и проверяем существует ли он
*/
$sTopicId=$this->GetParam(0);
if (!($oTopic=$this->Topic_GetTopicById($sTopicId))) {
return parent::EventNotFound();
}
/**
* Проверяем тип топика
*/
if ($oTopic->getType()!='photoset') {
return parent::EventNotFound();
}
/**
* Если права на редактирование
*/
if (!$this->ACL_IsAllowEditTopic($oTopic,$this->oUserCurrent)) {
return parent::EventNotFound();
}
/**
* Вызов хуков
*/
$this->Hook_Run('topic_edit_show',array('oTopic'=>$oTopic));
/**
* Загружаем переменные в шаблон
*/
$this->Viewer_Assign('aBlogsAllow',$this->Blog_GetBlogsAllowByUser($this->oUserCurrent));
$this->Viewer_Assign('sTopicType', $this->sType);
$this->Viewer_AddHtmlTitle($this->Lang_Get('topic_photoset_title_edit'));
/**
* Устанавливаем шаблон вывода
*/
$this->SetTemplateAction('add');
if (!is_numeric(getRequest('topic_id'))) {
$_REQUEST['topic_id']='';
}
/**
* Проверяем отправлена ли форма с данными(хотяб одна кнопка)
*/
if (isset($_REQUEST['submit_topic_publish']) or isset($_REQUEST['submit_topic_save'])) {
/**
* Обрабатываем отправку формы
*/
return $this->SubmitEdit($oTopic);
} else {
/**
* Заполняем поля формы для редактирования
* Только перед отправкой формы!
*/
$_REQUEST['topic_title']=$oTopic->getTitle();
$_REQUEST['topic_text']=$oTopic->getTextSource();
$_REQUEST['topic_tags']=$oTopic->getTags();
$_REQUEST['blog_id']=$oTopic->getBlogId();
$_REQUEST['topic_id']=$oTopic->getId();
$_REQUEST['topic_publish_index']=$oTopic->getPublishIndex();
$_REQUEST['topic_forbid_comment']=$oTopic->getForbidComment();
$_REQUEST['topic_main_photo']=$oTopic->getPhotosetMainPhotoId();
}
$this->Viewer_Assign('oTopicEdit', $oTopic);
$this->Viewer_Assign('aPhotos', $this->Topic_getPhotosByTopicId($oTopic->getId()));
}
/**
* Добавление топика
*
*/
protected function EventAdd() {
/**
* Проверяем авторизован ли юзер
*/
if (!$this->User_IsAuthorization()) {
$this->Message_AddErrorSingle($this->Lang_Get('not_access'),$this->Lang_Get('error'));
return Router::Action('error');
}
/**
* Вызов хуков
*/
$this->Hook_Run('topic_add_show');
/**
* Загружаем переменные в шаблон
*/
$this->Viewer_Assign('aBlogsAllow',$this->Blog_GetBlogsAllowByUser($this->oUserCurrent));
$this->Viewer_Assign('sTopicType', $this->sType);
$this->Viewer_AddHtmlTitle($this->Lang_Get('topic_photoset_title_create'));
if (!is_numeric(getRequest('topic_id'))) {
$_REQUEST['topic_id']='';
}
/**
* Если нет временного ключа для нового топика, то генерируеи. если есть, то загружаем фото по этому ключу
*/
if (empty($_COOKIE['ls_photoset_target_tmp']) or !is_string($_COOKIE['ls_photoset_target_tmp'])) {
setcookie('ls_photoset_target_tmp', func_generator(), time()+24*3600,Config::Get('sys.cookie.path'),Config::Get('sys.cookie.host'));
} else {
setcookie('ls_photoset_target_tmp', $_COOKIE['ls_photoset_target_tmp'], time()+24*3600,Config::Get('sys.cookie.path'),Config::Get('sys.cookie.host'));
$this->Viewer_Assign('aPhotos', $this->Topic_getPhotosByTargetTmp($_COOKIE['ls_photoset_target_tmp']));
}
/**
* Обрабатываем отправку формы
*/
return $this->SubmitAdd();
}
/**
* Обработка добавлени топика
*
* @return mixed
*/
protected function SubmitAdd() {
/**
* Проверяем отправлена ли форма с данными(хотяб одна кнопка)
*/
if (!isPost('submit_topic_publish') and !isPost('submit_topic_save')) {
return false;
}
$oTopic=Engine::GetEntity('Topic');
$oTopic->_setValidateScenario('photoset');
/**
* Заполняем поля для валидации
*/
$oTopic->setBlogId(getRequestStr('blog_id'));
$oTopic->setTitle(strip_tags(getRequestStr('topic_title')));
$oTopic->setTextSource(getRequestStr('topic_text'));
$oTopic->setTags(getRequestStr('topic_tags'));
$oTopic->setUserId($this->oUserCurrent->getId());
$oTopic->setType('photoset');
$oTopic->setDateAdd(date("Y-m-d H:i:s"));
$oTopic->setUserIp(func_getIp());
/**
* Проверка корректности полей формы
*/
if (!$this->checkTopicFields($oTopic)) {
return false;
}
/**
* Определяем в какой блог делаем запись
*/
$iBlogId=$oTopic->getBlogId();
if ($iBlogId==0) {
$oBlog=$this->Blog_GetPersonalBlogByUserId($this->oUserCurrent->getId());
} else {
$oBlog=$this->Blog_GetBlogById($iBlogId);
}
/**
* Если блог не определен выдаем предупреждение
*/
if (!$oBlog) {
$this->Message_AddErrorSingle($this->Lang_Get('topic_create_blog_error_unknown'),$this->Lang_Get('error'));
return false;
}
/**
* Проверяем права на постинг в блог
*/
if (!$this->ACL_IsAllowBlog($oBlog,$this->oUserCurrent)) {
$this->Message_AddErrorSingle($this->Lang_Get('topic_create_blog_error_noallow'),$this->Lang_Get('error'));
return false;
}
/**
* Проверяем разрешено ли постить топик по времени
*/
if (isPost('submit_topic_publish') and !$this->ACL_CanPostTopicTime($this->oUserCurrent)) {
$this->Message_AddErrorSingle($this->Lang_Get('topic_time_limit'),$this->Lang_Get('error'));
return;
}
/**
* Теперь можно смело добавлять топик к блогу
*/
$oTopic->setBlogId($oBlog->getId());
/**
* Получаемый и устанавливаем разрезанный текст по тегу <cut>
*/
list($sTextShort,$sTextNew,$sTextCut) = $this->Text_Cut($oTopic->getTextSource());
$oTopic->setCutText($sTextCut);
$oTopic->setText($this->Text_Parser($sTextNew));
$oTopic->setTextShort($this->Text_Parser($sTextShort));
$sTargetTmp=$_COOKIE['ls_photoset_target_tmp'];
$aPhotos = $this->Topic_getPhotosByTargetTmp($sTargetTmp);
if (!($oPhotoMain=$this->Topic_getTopicPhotoById(getRequestStr('topic_main_photo')) and $oPhotoMain->getTargetTmp()==$sTargetTmp)) {
$oPhotoMain=$aPhotos[0];
}
$oTopic->setPhotosetMainPhotoId($oPhotoMain->getId());
$oTopic->setPhotosetCount(count($aPhotos));
/**
* Публикуем или сохраняем
*/
if (isset($_REQUEST['submit_topic_publish'])) {
$oTopic->setPublish(1);
$oTopic->setPublishDraft(1);
} else {
$oTopic->setPublish(0);
$oTopic->setPublishDraft(0);
}
/**
* Принудительный вывод на главную
*/
$oTopic->setPublishIndex(0);
if ($this->ACL_IsAllowPublishIndex($this->oUserCurrent)) {
if (getRequest('topic_publish_index')) {
$oTopic->setPublishIndex(1);
}
}
/**
* Запрет на комментарии к топику
*/
$oTopic->setForbidComment(0);
if (getRequest('topic_forbid_comment')) {
$oTopic->setForbidComment(1);
}
/**
* Запускаем выполнение хуков
*/
$this->Hook_Run('topic_add_before', array('oTopic'=>$oTopic,'oBlog'=>$oBlog));
/**
* Добавляем топик
*/
if ($this->Topic_AddTopic($oTopic)) {
$this->Hook_Run('topic_add_after', array('oTopic'=>$oTopic,'oBlog'=>$oBlog));
/**
* Получаем топик, чтоб подцепить связанные данные
*/
$oTopic=$this->Topic_GetTopicById($oTopic->getId());
/**
* Обновляем количество топиков в блоге
*/
$this->Blog_RecalculateCountTopicByBlogId($oTopic->getBlogId());
/**
* Добавляем автора топика в подписчики на новые комментарии к этому топику
*/
$oUser=$oTopic->getUser();
if ($oUser) {
$this->Subscribe_AddSubscribeSimple('topic_new_comment',$oTopic->getId(),$oUser->getMail(),$oUser->getId());
}
/**
* Делаем рассылку спама всем, кто состоит в этом блоге
*/
if ($oTopic->getPublish()==1 and $oBlog->getType()!='personal') {
$this->Topic_SendNotifyTopicNew($oBlog,$oTopic,$oUser);
}
/**
* Привязываем фото к id топика
* здесь нужно это делать одним запросом, а не перебором сущностей
*/
if (count($aPhotos)) {
foreach($aPhotos as $oPhoto) {
$oPhoto->setTargetTmp(null);
$oPhoto->setTopicId($oTopic->getId());
$this->Topic_updateTopicPhoto($oPhoto);
}
}
/**
* Удаляем временную куку
*/
setcookie('ls_photoset_target_tmp', null);
/**
* Добавляем событие в ленту
*/
$this->Stream_write($oTopic->getUserId(), 'add_topic', $oTopic->getId(),$oTopic->getPublish() && $oBlog->getType()!='close');
Router::Location($oTopic->getUrl());
} else {
$this->Message_AddErrorSingle($this->Lang_Get('system_error'));
return Router::Action('error');
}
}
/**
* Обработка редактирования топика
*
* @param ModuleTopic_EntityTopic $oTopic
* @return mixed
*/
protected function SubmitEdit($oTopic) {
$oTopic->_setValidateScenario('photoset');
/**
* Сохраняем старое значение идентификатора блога
*/
$sBlogIdOld = $oTopic->getBlogId();
/**
* Заполняем поля для валидации
*/
$oTopic->setBlogId(getRequestStr('blog_id'));
$oTopic->setTitle(strip_tags(getRequestStr('topic_title')));
$oTopic->setTextSource(getRequestStr('topic_text'));
$oTopic->setTags(getRequestStr('topic_tags'));
$oTopic->setUserIp(func_getIp());
/**
* Проверка корректности полей формы
*/
if (!$this->checkTopicFields($oTopic)) {
return false;
}
/**
* Определяем в какой блог делаем запись
*/
$iBlogId=$oTopic->getBlogId();
if ($iBlogId==0) {
$oBlog=$this->Blog_GetPersonalBlogByUserId($oTopic->getUserId());
} else {
$oBlog=$this->Blog_GetBlogById($iBlogId);
}
/**
* Если блог не определен выдаем предупреждение
*/
if (!$oBlog) {
$this->Message_AddErrorSingle($this->Lang_Get('topic_create_blog_error_unknown'),$this->Lang_Get('error'));
return false;
}
/**
* Проверяем права на постинг в блог
*/
if (!$this->ACL_IsAllowBlog($oBlog,$this->oUserCurrent)) {
$this->Message_AddErrorSingle($this->Lang_Get('topic_create_blog_error_noallow'),$this->Lang_Get('error'));
return false;
}
/**
* Проверяем разрешено ли постить топик по времени
*/
if (isPost('submit_topic_publish') and !$oTopic->getPublishDraft() and !$this->ACL_CanPostTopicTime($this->oUserCurrent)) {
$this->Message_AddErrorSingle($this->Lang_Get('topic_time_limit'),$this->Lang_Get('error'));
return;
}
/**
* Теперь можно смело редактировать топик
*/
$oTopic->setBlogId($oBlog->getId());
/**
* Получаемый и устанавливаем разрезанный текст по тегу <cut>
*/
list($sTextShort,$sTextNew,$sTextCut) = $this->Text_Cut($oTopic->getTextSource());
$oTopic->setCutText($sTextCut);
$oTopic->setText($this->Text_Parser($sTextNew));
$oTopic->setTextShort($this->Text_Parser($sTextShort));
$aPhotos = $oTopic->getPhotosetPhotos();
if (!($oPhotoMain=$this->Topic_getTopicPhotoById(getRequestStr('topic_main_photo')) and $oPhotoMain->getTopicId()==$oTopic->getId())) {
$oPhotoMain=$aPhotos[0];
}
$oTopic->setPhotosetMainPhotoId($oPhotoMain->getId());
$oTopic->setPhotosetCount(count($aPhotos));
/**
* Публикуем или сохраняем в черновиках
*/
$bSendNotify=false;
if (isset($_REQUEST['submit_topic_publish'])) {
$oTopic->setPublish(1);
if ($oTopic->getPublishDraft()==0) {
$oTopic->setPublishDraft(1);
$oTopic->setDateAdd(date("Y-m-d H:i:s"));
$bSendNotify=true;
}
} else {
$oTopic->setPublish(0);
}
/**
* Принудительный вывод на главную
*/
if ($this->ACL_IsAllowPublishIndex($this->oUserCurrent)) {
if (getRequest('topic_publish_index')) {
$oTopic->setPublishIndex(1);
} else {
$oTopic->setPublishIndex(0);
}
}
/**
* Запрет на комментарии к топику
*/
$oTopic->setForbidComment(0);
if (getRequest('topic_forbid_comment')) {
$oTopic->setForbidComment(1);
}
$this->Hook_Run('topic_edit_before', array('oTopic'=>$oTopic,'oBlog'=>$oBlog));
/**
* Сохраняем топик
*/
if ($this->Topic_UpdateTopic($oTopic)) {
$this->Hook_Run('topic_edit_after', array('oTopic'=>$oTopic,'oBlog'=>$oBlog,'bSendNotify'=>&$bSendNotify));
/**
* Обновляем данные в комментариях, если топик был перенесен в новый блог
*/
if($sBlogIdOld!=$oTopic->getBlogId()) {
$this->Comment_UpdateTargetParentByTargetId($oTopic->getBlogId(), 'topic', $oTopic->getId());
$this->Comment_UpdateTargetParentByTargetIdOnline($oTopic->getBlogId(), 'topic', $oTopic->getId());
}
/**
* Обновляем количество топиков в блоге
*/
if ($sBlogIdOld!=$oTopic->getBlogId()) {
$this->Blog_RecalculateCountTopicByBlogId($sBlogIdOld);
}
$this->Blog_RecalculateCountTopicByBlogId($oTopic->getBlogId());
/**
* Добавляем событие в ленту
*/
$this->Stream_write($oTopic->getUserId(), 'add_topic', $oTopic->getId(),$oTopic->getPublish() && $oBlog->getType()!='close');
/**
* Рассылаем о новом топике подписчикам блога
*/
if ($bSendNotify) {
$this->Topic_SendNotifyTopicNew($oBlog,$oTopic,$oTopic->getUser());
}
if (!$oTopic->getPublish() and !$this->oUserCurrent->isAdministrator() and $this->oUserCurrent->getId()!=$oTopic->getUserId()) {
Router::Location($oBlog->getUrlFull());
}
Router::Location($oTopic->getUrl());
} else {
$this->Message_AddErrorSingle($this->Lang_Get('system_error'));
return Router::Action('error');
}
}
/**
* Проверка полей формы
*
* @return bool
*/
protected function checkTopicFields($oTopic) {
$this->Security_ValidateSendForm();
$bOk=true;
if (!$oTopic->_Validate()) {
$this->Message_AddError($oTopic->_getValidateError(),$this->Lang_Get('error'));
$bOk=false;
}
$sTargetId = null;
$iCountPhotos = 0;
if (!$oTopic->getTopicId()) {
if (isset($_COOKIE['ls_photoset_target_tmp']) and is_string($_COOKIE['ls_photoset_target_tmp'])) {
$iCountPhotos = $this->Topic_getCountPhotosByTargetTmp($_COOKIE['ls_photoset_target_tmp']);
} else {
$this->Message_AddError($this->Lang_Get('system_error'), $this->Lang_Get('error'));
return false;
}
} else {
$iCountPhotos = $this->Topic_getCountPhotosByTopicId($oTopic->getId());
}
if ($iCountPhotos < Config::Get('module.topic.photoset.count_photos_min') || $iCountPhotos > Config::Get('module.topic.photoset.count_photos_max')) {
$this->Message_AddError($this->Lang_Get('topic_photoset_error_count_photos', array('MIN' => Config::Get('module.topic.photoset.count_photos_min'), 'MAX' => Config::Get('module.topic.photoset.count_photos_max'))), $this->Lang_Get('error'));
return false;
}
/**
* Выполнение хуков
*/
$this->Hook_Run('check_photoset_fields', array('bOk'=>&$bOk));
return $bOk;
}
/**
* При завершении экшена загружаем необходимые переменные
*
*/
public function EventShutdown() {
$this->Viewer_Assign('sMenuHeadItemSelect',$this->sMenuHeadItemSelect);
$this->Viewer_Assign('sMenuItemSelect',$this->sMenuItemSelect);
$this->Viewer_Assign('sMenuSubItemSelect',$this->sMenuSubItemSelect);
}
}
?>

View file

@ -1,535 +0,0 @@
<?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
*
---------------------------------------------------------
*/
/**
* Экшен обработки УРЛа вида /question/ - управление своими топиками(тип: вопрос)
*
* @package actions
* @since 1.0
*/
class ActionQuestion extends Action {
/**
* Главное меню
*
* @var string
*/
protected $sMenuHeadItemSelect='blog';
/**
* Меню
*
* @var string
*/
protected $sMenuItemSelect='topic';
/**
* СубМеню
*
* @var string
*/
protected $sMenuSubItemSelect='question';
/**
* Текущий юзер
*
* @var ModuleUser_EntityUser|null
*/
protected $oUserCurrent=null;
/**
* Тип топика
*
* @var string
*/
protected $sType = 'question';
/**
* Инициализация
*
*/
public function Init() {
/**
* Проверяем авторизован ли юзер
*/
if (!$this->User_IsAuthorization()) {
$this->Message_AddErrorSingle($this->Lang_Get('not_access'),$this->Lang_Get('error'));
return Router::Action('error');
}
$this->oUserCurrent=$this->User_GetUserCurrent();
$this->SetDefaultEvent('add');
/**
* Устанавливаем title страницы
*/
$this->Viewer_AddHtmlTitle($this->Lang_Get('topic_question_title'));
/**
* Загружаем в шаблон JS текстовки
*/
$this->Lang_AddLangJs(array(
'topic_question_create_answers_error_max','delete'
));
}
/**
* Регистрируем евенты
*
*/
protected function RegisterEvent() {
$this->AddEvent('add','EventAdd');
$this->AddEvent('edit','EventEdit');
}
/**********************************************************************************
************************ РЕАЛИЗАЦИЯ ЭКШЕНА ***************************************
**********************************************************************************
*/
/**
* Редактирование топика
*
*/
protected function EventEdit() {
/**
* Получаем номер топика из УРЛ и проверяем существует ли он
*/
$sTopicId=$this->GetParam(0);
if (!($oTopic=$this->Topic_GetTopicById($sTopicId))) {
return parent::EventNotFound();
}
/**
* Проверяем тип топика
*/
if ($oTopic->getType()!='question') {
return parent::EventNotFound();
}
/**
* Если права на редактирование
*/
if (!$this->ACL_IsAllowEditTopic($oTopic,$this->oUserCurrent)) {
return parent::EventNotFound();
}
/**
* Вызов хуков
*/
$this->Hook_Run('topic_edit_show',array('oTopic'=>$oTopic));
/**
* Загружаем переменные в шаблон
*/
$this->Viewer_Assign('aBlogsAllow',$this->Blog_GetBlogsAllowByUser($this->oUserCurrent));
$this->Viewer_Assign('bEditDisabled',$oTopic->getQuestionCountVote()==0 ? false : true);
$this->Viewer_Assign('sTopicType', $this->sType);
$this->Viewer_AddHtmlTitle($this->Lang_Get('topic_question_title_edit'));
/**
* Устанавливаем шаблон вывода
*/
$this->SetTemplateAction('add');
/**
* Проверяем отправлена ли форма с данными(хотяб одна кнопка)
*/
if (isset($_REQUEST['submit_topic_publish']) or isset($_REQUEST['submit_topic_save'])) {
/**
* Обрабатываем отправку формы
*/
return $this->SubmitEdit($oTopic);
} else {
/**
* Заполняем поля формы для редактирования
* Только перед отправкой формы!
*/
$_REQUEST['topic_title']=$oTopic->getTitle();
$_REQUEST['topic_text']=$oTopic->getTextSource();
$_REQUEST['topic_tags']=$oTopic->getTags();
$_REQUEST['blog_id']=$oTopic->getBlogId();
$_REQUEST['topic_id']=$oTopic->getId();
$_REQUEST['topic_publish_index']=$oTopic->getPublishIndex();
$_REQUEST['topic_forbid_comment']=$oTopic->getForbidComment();
$_REQUEST['answer']=array();
$aAnswers=$oTopic->getQuestionAnswers();
foreach ($aAnswers as $aAnswer) {
$_REQUEST['answer'][]=$aAnswer['text'];
}
}
$this->Viewer_Assign('oTopicEdit', $oTopic);
}
/**
* Добавление топика
*
*/
protected function EventAdd() {
/**
* Вызов хуков
*/
$this->Hook_Run('topic_add_show');
/**
* Загружаем переменные в шаблон
*/
$this->Viewer_Assign('aBlogsAllow',$this->Blog_GetBlogsAllowByUser($this->oUserCurrent));
$this->Viewer_Assign('bEditDisabled',false);
$this->Viewer_Assign('sTopicType', $this->sType);
$this->Viewer_AddHtmlTitle($this->Lang_Get('topic_question_title_create'));
/**
* Обрабатываем отправку формы
*/
return $this->SubmitAdd();
}
/**
* Обработка добавлени топика
*
* @return mixed
*/
protected function SubmitAdd() {
/**
* Проверяем отправлена ли форма с данными(хотяб одна кнопка)
*/
if (!isPost('submit_topic_publish') and !isPost('submit_topic_save')) {
return false;
}
$oTopic=Engine::GetEntity('Topic');
$oTopic->_setValidateScenario('question');
/**
* Заполняем поля для валидации
*/
$oTopic->setBlogId(getRequestStr('blog_id'));
$oTopic->setTitle(strip_tags(getRequestStr('topic_title')));
$oTopic->setTextSource(getRequestStr('topic_text'));
$oTopic->setTags(getRequestStr('topic_tags'));
$oTopic->setUserId($this->oUserCurrent->getId());
$oTopic->setType('question');
$oTopic->setDateAdd(date("Y-m-d H:i:s"));
$oTopic->setUserIp(func_getIp());
/**
* Проверка корректности полей формы
*/
if (!$this->checkTopicFields($oTopic)) {
return false;
}
/**
* Определяем в какой блог делаем запись
*/
$iBlogId=$oTopic->getBlogId();
if ($iBlogId==0) {
$oBlog=$this->Blog_GetPersonalBlogByUserId($this->oUserCurrent->getId());
} else {
$oBlog=$this->Blog_GetBlogById($iBlogId);
}
/**
* Если блог не определен выдаем предупреждение
*/
if (!$oBlog) {
$this->Message_AddErrorSingle($this->Lang_Get('topic_create_blog_error_unknown'),$this->Lang_Get('error'));
return false;
}
/**
* Проверяем права на постинг в блог
*/
if (!$this->ACL_IsAllowBlog($oBlog,$this->oUserCurrent)) {
$this->Message_AddErrorSingle($this->Lang_Get('topic_create_blog_error_noallow'),$this->Lang_Get('error'));
return false;
}
/**
* Проверяем разрешено ли постить топик по времени
*/
if (isPost('submit_topic_publish') and !$this->ACL_CanPostTopicTime($this->oUserCurrent)) {
$this->Message_AddErrorSingle($this->Lang_Get('topic_time_limit'),$this->Lang_Get('error'));
return;
}
/**
* Теперь можно смело добавлять топик к блогу
*/
$oTopic->setBlogId($oBlog->getId());
$oTopic->setText($this->Text_Parser($oTopic->getTextSource()));
$oTopic->setTextShort($oTopic->getText());
$oTopic->setCutText(null);
/**
* Варианты ответов
*/
$oTopic->clearQuestionAnswer();
foreach (getRequest('answer',array()) as $sAnswer) {
$oTopic->addQuestionAnswer((string)$sAnswer);
}
/**
* Публикуем или сохраняем
*/
if (isset($_REQUEST['submit_topic_publish'])) {
$oTopic->setPublish(1);
$oTopic->setPublishDraft(1);
} else {
$oTopic->setPublish(0);
$oTopic->setPublishDraft(0);
}
/**
* Принудительный вывод на главную
*/
$oTopic->setPublishIndex(0);
if ($this->ACL_IsAllowPublishIndex($this->oUserCurrent)) {
if (getRequest('topic_publish_index')) {
$oTopic->setPublishIndex(1);
}
}
/**
* Запрет на комментарии к топику
*/
$oTopic->setForbidComment(0);
if (getRequest('topic_forbid_comment')) {
$oTopic->setForbidComment(1);
}
/**
* Запускаем выполнение хуков
*/
$this->Hook_Run('topic_add_before', array('oTopic'=>$oTopic,'oBlog'=>$oBlog));
/**
* Добавляем топик
*/
if ($this->Topic_AddTopic($oTopic)) {
$this->Hook_Run('topic_add_after', array('oTopic'=>$oTopic,'oBlog'=>$oBlog));
/**
* Получаем топик, чтоб подцепить связанные данные
*/
$oTopic=$this->Topic_GetTopicById($oTopic->getId());
/**
* Обновляем количество топиков в блоге
*/
$this->Blog_RecalculateCountTopicByBlogId($oTopic->getBlogId());
/**
* Добавляем автора топика в подписчики на новые комментарии к этому топику
*/
$oUser=$oTopic->getUser();
if ($oUser) {
$this->Subscribe_AddSubscribeSimple('topic_new_comment',$oTopic->getId(),$oUser->getMail(),$oUser->getId());
}
/**
* Делаем рассылку спама всем, кто состоит в этом блоге
*/
if ($oTopic->getPublish()==1 and $oBlog->getType()!='personal') {
$this->Topic_SendNotifyTopicNew($oBlog,$oTopic,$oUser);
}
/**
* Добавляем событие в ленту
*/
$this->Stream_write($oTopic->getUserId(), 'add_topic', $oTopic->getId(),$oTopic->getPublish() && $oBlog->getType()!='close');
Router::Location($oTopic->getUrl());
} else {
$this->Message_AddErrorSingle($this->Lang_Get('system_error'));
return Router::Action('error');
}
}
/**
* Обработка редактирования топика
*
* @param ModuleTopic_EntityTopic $oTopic
* @return mixed
*/
protected function SubmitEdit($oTopic) {
$oTopic->_setValidateScenario('question');
/**
* Сохраняем старое значение идентификатора блога
*/
$sBlogIdOld = $oTopic->getBlogId();
/**
* Заполняем поля для валидации
*/
$oTopic->setBlogId(getRequestStr('blog_id'));
if ($oTopic->getQuestionCountVote()==0) {
$oTopic->setTitle(strip_tags(getRequestStr('topic_title')));
}
$oTopic->setTextSource(getRequestStr('topic_text'));
$oTopic->setTags(getRequestStr('topic_tags'));
$oTopic->setUserIp(func_getIp());
/**
* Проверка корректности полей формы
*/
if (!$this->checkTopicFields($oTopic)) {
return false;
}
/**
* Определяем в какой блог делаем запись
*/
$iBlogId=$oTopic->getBlogId();
if ($iBlogId==0) {
$oBlog=$this->Blog_GetPersonalBlogByUserId($oTopic->getUserId());
} else {
$oBlog=$this->Blog_GetBlogById($iBlogId);
}
/**
* Если блог не определен выдаем предупреждение
*/
if (!$oBlog) {
$this->Message_AddErrorSingle($this->Lang_Get('topic_create_blog_error_unknown'),$this->Lang_Get('error'));
return false;
}
/**
* Проверяем права на постинг в блог
*/
if (!$this->ACL_IsAllowBlog($oBlog,$this->oUserCurrent)) {
$this->Message_AddErrorSingle($this->Lang_Get('topic_create_blog_error_noallow'),$this->Lang_Get('error'));
return false;
}
/**
* Проверяем разрешено ли постить топик по времени
*/
if (isPost('submit_topic_publish') and !$oTopic->getPublishDraft() and !$this->ACL_CanPostTopicTime($this->oUserCurrent)) {
$this->Message_AddErrorSingle($this->Lang_Get('topic_time_limit'),$this->Lang_Get('error'));
return;
}
/**
* Теперь можно смело редактировать топик
*/
$oTopic->setBlogId($oBlog->getId());
$oTopic->setText($this->Text_Parser($oTopic->getTextSource()));
$oTopic->setTextShort($oTopic->getText());
/**
* изменяем вопрос/ответы только если еще никто не голосовал
*/
if ($oTopic->getQuestionCountVote()==0) {
$oTopic->clearQuestionAnswer();
foreach (getRequest('answer',array()) as $sAnswer) {
$oTopic->addQuestionAnswer((string)$sAnswer);
}
}
/**
* Публикуем или сохраняем в черновиках
*/
$bSendNotify=false;
if (isset($_REQUEST['submit_topic_publish'])) {
$oTopic->setPublish(1);
if ($oTopic->getPublishDraft()==0) {
$oTopic->setPublishDraft(1);
$oTopic->setDateAdd(date("Y-m-d H:i:s"));
$bSendNotify=true;
}
} else {
$oTopic->setPublish(0);
}
/**
* Принудительный вывод на главную
*/
if ($this->ACL_IsAllowPublishIndex($this->oUserCurrent)) {
if (getRequest('topic_publish_index')) {
$oTopic->setPublishIndex(1);
} else {
$oTopic->setPublishIndex(0);
}
}
/**
* Запрет на комментарии к топику
*/
$oTopic->setForbidComment(0);
if (getRequest('topic_forbid_comment')) {
$oTopic->setForbidComment(1);
}
$this->Hook_Run('topic_edit_before', array('oTopic'=>$oTopic,'oBlog'=>$oBlog));
/**
* Сохраняем топик
*/
if ($this->Topic_UpdateTopic($oTopic)) {
$this->Hook_Run('topic_edit_after', array('oTopic'=>$oTopic,'oBlog'=>$oBlog,'bSendNotify'=>&$bSendNotify));
/**
* Обновляем данные в комментариях, если топик был перенесен в новый блог
*/
if($sBlogIdOld!=$oTopic->getBlogId()) {
$this->Comment_UpdateTargetParentByTargetId($oTopic->getBlogId(), 'topic', $oTopic->getId());
$this->Comment_UpdateTargetParentByTargetIdOnline($oTopic->getBlogId(), 'topic', $oTopic->getId());
}
/**
* Обновляем количество топиков в блоге
*/
if ($sBlogIdOld!=$oTopic->getBlogId()) {
$this->Blog_RecalculateCountTopicByBlogId($sBlogIdOld);
}
$this->Blog_RecalculateCountTopicByBlogId($oTopic->getBlogId());
/**
* Добавляем событие в ленту
*/
$this->Stream_write($oTopic->getUserId(), 'add_topic', $oTopic->getId(),$oTopic->getPublish() && $oBlog->getType()!='close');
/**
* Рассылаем о новом топике подписчикам блога
*/
if ($bSendNotify) {
$this->Topic_SendNotifyTopicNew($oBlog,$oTopic,$oTopic->getUser());
}
if (!$oTopic->getPublish() and !$this->oUserCurrent->isAdministrator() and $this->oUserCurrent->getId()!=$oTopic->getUserId()) {
Router::Location($oBlog->getUrlFull());
}
Router::Location($oTopic->getUrl());
} else {
$this->Message_AddErrorSingle($this->Lang_Get('system_error'));
return Router::Action('error');
}
}
/**
* Проверка полей формы
*
* @param ModuleTopic_EntityTopic $oTopic
* @return bool
*/
protected function checkTopicFields($oTopic) {
$this->Security_ValidateSendForm();
$bOk=true;
if (!$oTopic->_Validate()) {
$this->Message_AddError($oTopic->_getValidateError(),$this->Lang_Get('error'));
$bOk=false;
}
/**
* проверяем заполнение ответов только если еще никто не голосовал
*/
if ($oTopic->getQuestionCountVote()==0) {
/**
* Проверяем варианты ответов
*/
$aAnswers=getRequest('answer',array());
foreach ($aAnswers as $key => $sAnswer) {
$sAnswer=(string)$sAnswer;
if (trim($sAnswer)=='') {
unset($aAnswers[$key]);
continue;
}
if (!func_check($sAnswer,'text',1,100)) {
$this->Message_AddError($this->Lang_Get('topic_question_create_answers_error'),$this->Lang_Get('error'));
$bOk=false;
break;
}
}
$_REQUEST['answer']=$aAnswers;
/**
* Ограничения на количество вариантов
*/
if (count($aAnswers)<2) {
$this->Message_AddError($this->Lang_Get('topic_question_create_answers_error_min'),$this->Lang_Get('error'));
$bOk=false;
}
if (count($aAnswers)>20) {
$this->Message_AddError($this->Lang_Get('topic_question_create_answers_error_max'),$this->Lang_Get('error'));
$bOk=false;
}
}
/**
* Выполнение хуков
*/
$this->Hook_Run('check_question_fields', array('bOk'=>&$bOk));
return $bOk;
}
/**
* При завершении экшена загружаем необходимые переменные
*
*/
public function EventShutdown() {
$this->Viewer_Assign('sMenuHeadItemSelect',$this->sMenuHeadItemSelect);
$this->Viewer_Assign('sMenuItemSelect',$this->sMenuItemSelect);
$this->Viewer_Assign('sMenuSubItemSelect',$this->sMenuSubItemSelect);
}
}
?>

View file

@ -1,555 +0,0 @@
<?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
*
---------------------------------------------------------
*/
/**
* Экшен обработки УРЛа вида /topic/ - управление своими топиками
*
* @package actions
* @since 1.0
*/
class ActionTopic extends Action {
/**
* Главное меню
*
* @var string
*/
protected $sMenuHeadItemSelect='blog';
/**
* Меню
*
* @var string
*/
protected $sMenuItemSelect='topic';
/**
* СубМеню
*
* @var string
*/
protected $sMenuSubItemSelect='topic';
/**
* Текущий юзер
*
* @var ModuleUser_EntityUser|null
*/
protected $oUserCurrent=null;
/**
* Тип топика
*
* @var string
*/
protected $sType = 'topic';
/**
* Инициализация
*
*/
public function Init() {
/**
* Проверяем авторизован ли юзер
*/
if (!$this->User_IsAuthorization()) {
return parent::EventNotFound();
}
$this->oUserCurrent=$this->User_GetUserCurrent();
/**
* Усанавливаем дефолтный евент
*/
$this->SetDefaultEvent('add');
/**
* Устанавливаем title страницы
*/
$this->Viewer_AddHtmlTitle($this->Lang_Get('topic_title'));
}
/**
* Регистрируем евенты
*
*/
protected function RegisterEvent() {
$this->AddEvent('add','EventAdd');
$this->AddEventPreg('/^published$/i','/^(page([1-9]\d{0,5}))?$/i','EventShowTopics');
$this->AddEventPreg('/^drafts$/i','/^(page([1-9]\d{0,5}))?$/i','EventShowTopics');
$this->AddEvent('edit','EventEdit');
$this->AddEvent('delete','EventDelete');
}
/**********************************************************************************
************************ РЕАЛИЗАЦИЯ ЭКШЕНА ***************************************
**********************************************************************************
*/
/**
* Редактирование топика
*
*/
protected function EventEdit() {
/**
* Получаем номер топика из УРЛ и проверяем существует ли он
*/
$sTopicId=$this->GetParam(0);
if (!($oTopic=$this->Topic_GetTopicById($sTopicId))) {
return parent::EventNotFound();
}
/**
* Проверяем тип топика
*/
if ($oTopic->getType()!='topic') {
return parent::EventNotFound();
}
/**
* Если права на редактирование
*/
if (!$this->ACL_IsAllowEditTopic($oTopic,$this->oUserCurrent)) {
return parent::EventNotFound();
}
/**
* Вызов хуков
*/
$this->Hook_Run('topic_edit_show',array('oTopic'=>$oTopic));
/**
* Загружаем переменные в шаблон
*/
$this->Viewer_Assign('aBlogsAllow',$this->Blog_GetBlogsAllowByUser($this->oUserCurrent));
$this->Viewer_Assign('sTopicType', $this->sType);
$this->Viewer_AddHtmlTitle($this->Lang_Get('topic_topic_edit'));
/**
* Устанавливаем шаблон вывода
*/
$this->SetTemplateAction('add');
/**
* Проверяем отправлена ли форма с данными(хотяб одна кнопка)
*/
if (isset($_REQUEST['submit_topic_publish']) or isset($_REQUEST['submit_topic_save'])) {
/**
* Обрабатываем отправку формы
*/
return $this->SubmitEdit($oTopic);
} else {
/**
* Заполняем поля формы для редактирования
* Только перед отправкой формы!
*/
$_REQUEST['topic_title']=$oTopic->getTitle();
$_REQUEST['topic_text']=$oTopic->getTextSource();
$_REQUEST['topic_tags']=$oTopic->getTags();
$_REQUEST['blog_id']=$oTopic->getBlogId();
$_REQUEST['topic_id']=$oTopic->getId();
$_REQUEST['topic_publish_index']=$oTopic->getPublishIndex();
$_REQUEST['topic_forbid_comment']=$oTopic->getForbidComment();
}
$this->Viewer_Assign('oTopicEdit', $oTopic);
}
/**
* Удаление топика
*
*/
protected function EventDelete() {
$this->Security_ValidateSendForm();
/**
* Получаем номер топика из УРЛ и проверяем существует ли он
*/
$sTopicId=$this->GetParam(0);
if (!($oTopic=$this->Topic_GetTopicById($sTopicId))) {
return parent::EventNotFound();
}
/**
* проверяем есть ли право на удаление топика
*/
if (!$this->ACL_IsAllowDeleteTopic($oTopic,$this->oUserCurrent)) {
return parent::EventNotFound();
}
/**
* Удаляем топик
*/
$this->Hook_Run('topic_delete_before', array('oTopic'=>$oTopic));
$this->Topic_DeleteTopic($oTopic);
$this->Hook_Run('topic_delete_after', array('oTopic'=>$oTopic));
/**
* Перенаправляем на страницу со списком топиков из блога этого топика
*/
Router::Location($oTopic->getBlog()->getUrlFull());
}
/**
* Добавление топика
*
*/
protected function EventAdd() {
/**
* Вызов хуков
*/
$this->Hook_Run('topic_add_show');
/**
* Загружаем переменные в шаблон
*/
$this->Viewer_Assign('aBlogsAllow',$this->Blog_GetBlogsAllowByUser($this->oUserCurrent));
$this->Viewer_Assign('sTopicType', $this->sType);
$this->Viewer_AddHtmlTitle($this->Lang_Get('topic_topic_create'));
/**
* Обрабатываем отправку формы
*/
return $this->SubmitAdd();
}
/**
* Выводит список топиков
*
*/
protected function EventShowTopics() {
/**
* Меню
*/
$this->sMenuSubItemSelect=$this->sCurrentEvent;
/**
* Передан ли номер страницы
*/
$iPage=$this->GetParamEventMatch(0,2) ? $this->GetParamEventMatch(0,2) : 1;
/**
* Получаем список топиков
*/
$aResult=$this->Topic_GetTopicsPersonalByUser($this->oUserCurrent->getId(),$this->sCurrentEvent=='published' ? 1 : 0,$iPage,Config::Get('module.topic.per_page'));
$aTopics=$aResult['collection'];
/**
* Формируем постраничность
*/
$aPaging=$this->Viewer_MakePaging($aResult['count'],$iPage,Config::Get('module.topic.per_page'),Config::Get('pagination.pages.count'),Router::GetPath('topic').$this->sCurrentEvent);
/**
* Загружаем переменные в шаблон
*/
$this->Viewer_Assign('aPaging',$aPaging);
$this->Viewer_Assign('aTopics',$aTopics);
$this->Viewer_AddHtmlTitle($this->Lang_Get('topic_menu_'.$this->sCurrentEvent));
}
/**
* Обработка добавления топика
*
*/
protected function SubmitAdd() {
/**
* Проверяем отправлена ли форма с данными(хотяб одна кнопка)
*/
if (!isPost('submit_topic_publish') and !isPost('submit_topic_save')) {
return false;
}
$oTopic=Engine::GetEntity('Topic');
$oTopic->_setValidateScenario('topic');
/**
* Заполняем поля для валидации
*/
$oTopic->setBlogId(getRequestStr('blog_id'));
$oTopic->setTitle(strip_tags(getRequestStr('topic_title')));
$oTopic->setTextSource(getRequestStr('topic_text'));
$oTopic->setTags(getRequestStr('topic_tags'));
$oTopic->setUserId($this->oUserCurrent->getId());
$oTopic->setType('topic');
$oTopic->setDateAdd(date("Y-m-d H:i:s"));
$oTopic->setUserIp(func_getIp());
/**
* Проверка корректности полей формы
*/
if (!$this->checkTopicFields($oTopic)) {
return false;
}
/**
* Определяем в какой блог делаем запись
*/
$iBlogId=$oTopic->getBlogId();
if ($iBlogId==0) {
$oBlog=$this->Blog_GetPersonalBlogByUserId($this->oUserCurrent->getId());
} else {
$oBlog=$this->Blog_GetBlogById($iBlogId);
}
/**
* Если блог не определен выдаем предупреждение
*/
if (!$oBlog) {
$this->Message_AddErrorSingle($this->Lang_Get('topic_create_blog_error_unknown'),$this->Lang_Get('error'));
return false;
}
/**
* Проверяем права на постинг в блог
*/
if (!$this->ACL_IsAllowBlog($oBlog,$this->oUserCurrent)) {
$this->Message_AddErrorSingle($this->Lang_Get('topic_create_blog_error_noallow'),$this->Lang_Get('error'));
return false;
}
/**
* Проверяем разрешено ли постить топик по времени
*/
if (isPost('submit_topic_publish') and !$this->ACL_CanPostTopicTime($this->oUserCurrent)) {
$this->Message_AddErrorSingle($this->Lang_Get('topic_time_limit'),$this->Lang_Get('error'));
return;
}
/**
* Теперь можно смело добавлять топик к блогу
*/
$oTopic->setBlogId($oBlog->getId());
/**
* Получаемый и устанавливаем разрезанный текст по тегу <cut>
*/
list($sTextShort,$sTextNew,$sTextCut) = $this->Text_Cut($oTopic->getTextSource());
$oTopic->setCutText($sTextCut);
$oTopic->setText($this->Text_Parser($sTextNew));
$oTopic->setTextShort($this->Text_Parser($sTextShort));
/**
* Публикуем или сохраняем
*/
if (isset($_REQUEST['submit_topic_publish'])) {
$oTopic->setPublish(1);
$oTopic->setPublishDraft(1);
} else {
$oTopic->setPublish(0);
$oTopic->setPublishDraft(0);
}
/**
* Принудительный вывод на главную
*/
$oTopic->setPublishIndex(0);
if ($this->ACL_IsAllowPublishIndex($this->oUserCurrent)) {
if (getRequest('topic_publish_index')) {
$oTopic->setPublishIndex(1);
}
}
/**
* Запрет на комментарии к топику
*/
$oTopic->setForbidComment(0);
if (getRequest('topic_forbid_comment')) {
$oTopic->setForbidComment(1);
}
/**
* Запускаем выполнение хуков
*/
$this->Hook_Run('topic_add_before', array('oTopic'=>$oTopic,'oBlog'=>$oBlog));
/**
* Добавляем топик
*/
if ($this->Topic_AddTopic($oTopic)) {
$this->Hook_Run('topic_add_after', array('oTopic'=>$oTopic,'oBlog'=>$oBlog));
/**
* Получаем топик, чтоб подцепить связанные данные
*/
$oTopic=$this->Topic_GetTopicById($oTopic->getId());
/**
* Обновляем количество топиков в блоге
*/
$this->Blog_RecalculateCountTopicByBlogId($oTopic->getBlogId());
/**
* Фиксируем ID у media файлов топика
*/
if (isset($_COOKIE['media_target_tmp_topic']) and is_string($_COOKIE['media_target_tmp_topic'])) {
$aTargetItems=$this->Media_GetTargetItemsByTargetTmpAndTargetType($_COOKIE['media_target_tmp_topic'],'topic');
foreach($aTargetItems as $oTarget) {
$oTarget->setTargetTmp(null);
$oTarget->setTargetId($oTopic->getId());
$oTarget->Update();
}
}
setcookie('media_target_tmp_topic',null);
/**
* Добавляем автора топика в подписчики на новые комментарии к этому топику
*/
$oUser=$oTopic->getUser();
if ($oUser) {
$this->Subscribe_AddSubscribeSimple('topic_new_comment',$oTopic->getId(),$oUser->getMail(),$oUser->getId());
}
/**
* Делаем рассылку спама всем, кто состоит в этом блоге
*/
if ($oTopic->getPublish()==1 and $oBlog->getType()!='personal') {
$this->Topic_SendNotifyTopicNew($oBlog,$oTopic,$oUser);
}
/**
* Добавляем событие в ленту
*/
$this->Stream_write($oTopic->getUserId(), 'add_topic', $oTopic->getId(),$oTopic->getPublish() && $oBlog->getType()!='close');
Router::Location($oTopic->getUrl());
} else {
$this->Message_AddErrorSingle($this->Lang_Get('system_error'));
return Router::Action('error');
}
}
/**
* Обработка редактирования топика
*
* @param ModuleTopic_EntityTopic $oTopic
* @return mixed
*/
protected function SubmitEdit($oTopic) {
$oTopic->_setValidateScenario('topic');
/**
* Сохраняем старое значение идентификатора блога
*/
$sBlogIdOld = $oTopic->getBlogId();
/**
* Заполняем поля для валидации
*/
$oTopic->setBlogId(getRequestStr('blog_id'));
$oTopic->setTitle(strip_tags(getRequestStr('topic_title')));
$oTopic->setTextSource(getRequestStr('topic_text'));
$oTopic->setTags(getRequestStr('topic_tags'));
$oTopic->setUserIp(func_getIp());
/**
* Проверка корректности полей формы
*/
if (!$this->checkTopicFields($oTopic)) {
return false;
}
/**
* Определяем в какой блог делаем запись
*/
$iBlogId=$oTopic->getBlogId();
if ($iBlogId==0) {
$oBlog=$this->Blog_GetPersonalBlogByUserId($oTopic->getUserId());
} else {
$oBlog=$this->Blog_GetBlogById($iBlogId);
}
/**
* Если блог не определен выдаем предупреждение
*/
if (!$oBlog) {
$this->Message_AddErrorSingle($this->Lang_Get('topic_create_blog_error_unknown'),$this->Lang_Get('error'));
return false;
}
/**
* Проверяем права на постинг в блог
*/
if (!$this->ACL_IsAllowBlog($oBlog,$this->oUserCurrent)) {
$this->Message_AddErrorSingle($this->Lang_Get('topic_create_blog_error_noallow'),$this->Lang_Get('error'));
return false;
}
/**
* Проверяем разрешено ли постить топик по времени
*/
if (isPost('submit_topic_publish') and !$oTopic->getPublishDraft() and !$this->ACL_CanPostTopicTime($this->oUserCurrent)) {
$this->Message_AddErrorSingle($this->Lang_Get('topic_time_limit'),$this->Lang_Get('error'));
return;
}
$oTopic->setBlogId($oBlog->getId());
/**
* Получаемый и устанавливаем разрезанный текст по тегу <cut>
*/
list($sTextShort,$sTextNew,$sTextCut) = $this->Text_Cut($oTopic->getTextSource());
$oTopic->setCutText($sTextCut);
// TODO: передача параметров в Topic_Parser пока не используется - нужно заменить на этот вызов все места с парсингом топика
$oTopic->setText($this->Topic_Parser($sTextNew,$oTopic));
$oTopic->setTextShort($this->Topic_Parser($sTextShort,$oTopic));
/**
* Публикуем или сохраняем в черновиках
*/
$bSendNotify=false;
if (isset($_REQUEST['submit_topic_publish'])) {
$oTopic->setPublish(1);
if ($oTopic->getPublishDraft()==0) {
$oTopic->setPublishDraft(1);
$oTopic->setDateAdd(date("Y-m-d H:i:s"));
$bSendNotify=true;
}
} else {
$oTopic->setPublish(0);
}
/**
* Принудительный вывод на главную
*/
if ($this->ACL_IsAllowPublishIndex($this->oUserCurrent)) {
if (getRequest('topic_publish_index')) {
$oTopic->setPublishIndex(1);
} else {
$oTopic->setPublishIndex(0);
}
}
/**
* Запрет на комментарии к топику
*/
$oTopic->setForbidComment(0);
if (getRequest('topic_forbid_comment')) {
$oTopic->setForbidComment(1);
}
$this->Hook_Run('topic_edit_before', array('oTopic'=>$oTopic,'oBlog'=>$oBlog));
/**
* Сохраняем топик
*/
if ($this->Topic_UpdateTopic($oTopic)) {
$this->Hook_Run('topic_edit_after', array('oTopic'=>$oTopic,'oBlog'=>$oBlog,'bSendNotify'=>&$bSendNotify));
/**
* Обновляем данные в комментариях, если топик был перенесен в новый блог
*/
if($sBlogIdOld!=$oTopic->getBlogId()) {
$this->Comment_UpdateTargetParentByTargetId($oTopic->getBlogId(), 'topic', $oTopic->getId());
$this->Comment_UpdateTargetParentByTargetIdOnline($oTopic->getBlogId(), 'topic', $oTopic->getId());
}
/**
* Обновляем количество топиков в блоге
*/
if ($sBlogIdOld!=$oTopic->getBlogId()) {
$this->Blog_RecalculateCountTopicByBlogId($sBlogIdOld);
}
$this->Blog_RecalculateCountTopicByBlogId($oTopic->getBlogId());
/**
* Добавляем событие в ленту
*/
$this->Stream_write($oTopic->getUserId(), 'add_topic', $oTopic->getId(),$oTopic->getPublish() && $oBlog->getType()!='close');
/**
* Рассылаем о новом топике подписчикам блога
*/
if ($bSendNotify) {
$this->Topic_SendNotifyTopicNew($oBlog,$oTopic,$oTopic->getUser());
}
if (!$oTopic->getPublish() and !$this->oUserCurrent->isAdministrator() and $this->oUserCurrent->getId()!=$oTopic->getUserId()) {
Router::Location($oBlog->getUrlFull());
}
Router::Location($oTopic->getUrl());
} else {
$this->Message_AddErrorSingle($this->Lang_Get('system_error'));
return Router::Action('error');
}
}
/**
* Проверка полей формы
*
* @return bool
*/
protected function checkTopicFields($oTopic) {
$this->Security_ValidateSendForm();
$bOk=true;
/**
* Валидируем топик
*/
if (!$oTopic->_Validate()) {
$this->Message_AddError($oTopic->_getValidateError(),$this->Lang_Get('error'));
$bOk=false;
}
/**
* Выполнение хуков
*/
$this->Hook_Run('check_topic_fields', array('bOk'=>&$bOk));
return $bOk;
}
/**
* При завершении экшена загружаем необходимые переменные
*
*/
public function EventShutdown() {
$this->Viewer_Assign('sMenuHeadItemSelect',$this->sMenuHeadItemSelect);
$this->Viewer_Assign('sMenuItemSelect',$this->sMenuItemSelect);
$this->Viewer_Assign('sMenuSubItemSelect',$this->sMenuSubItemSelect);
}
}
?>

View file

@ -40,8 +40,15 @@ class HookProperty extends Hook {
* Добавляем через наследование в объекты необходимый функционал по работе со свойствами EAV
*/
$aTargetTypes=$this->Property_GetTargetTypes();
$aUseEntities=array();
foreach($aTargetTypes as $sType=>$aParams) {
$this->Plugin_Inherit($aParams['entity'],'ModuleProperty_Target_'.$aParams['entity'],'ModuleProperty');
/**
* Защита от дубля при наследовании
*/
if (!in_array($aParams['entity'],$aUseEntities)) {
$this->Plugin_Inherit($aParams['entity'],'ModuleProperty_Target_'.$aParams['entity'],'ModuleProperty');
$aUseEntities[]=$aParams['entity'];
}
}
}
/**
@ -66,6 +73,8 @@ class HookProperty extends Hook {
/**
* Автозагрузчик классов
* Создает новый фейковый класс для создания цепочки наследования
* Поддерживаются только ORM сущности
* TODO: продумать использование сценариев валидации отличных от дефолтного
*
* @param string $sClassName
*/

View file

@ -0,0 +1,43 @@
<?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 HookTopicType extends Hook {
public function RegisterHook() {
$this->AddHook('lang_init_start','InitStart');
}
public function InitStart() {
/**
* Получаем список типов топиков
*/
$aTopicTypeItems=$this->Topic_GetTopicTypeItems();
foreach($aTopicTypeItems as $oType) {
/**
* Запускаем механизм свойств(дополнительныз полей) для каждого вида топика
*/
$this->Property_AddTargetType('topic_'.$oType->getCode(),array('entity'=>'ModuleTopic_EntityTopic','name'=>'Топик - '.$oType->getName()));
}
}
}

View file

@ -558,7 +558,7 @@ class ModuleComment extends Module {
if(!$aComments = $this->GetCommentsByTargetId($sTargetId,$sTargetType)) {
return false;
}
if(!isset($aComments['comments']) or count($aComments)==0) {
if(!isset($aComments['comments']) or count($aComments['comments'])==0) {
return;
}

View file

@ -22,6 +22,9 @@
* @since 1.0
*/
class ModuleTopic extends Module {
const TOPIC_TYPE_STATE_ACTIVE=1;
const TOPIC_TYPE_STATE_NOT_ACTIVE=0;
/**
* Объект маппера
*
@ -40,7 +43,7 @@ class ModuleTopic extends Module {
* @var array
*/
protected $aTopicTypes=array(
'topic','link','question','photoset'
);
/**
@ -50,27 +53,22 @@ class ModuleTopic extends Module {
public function Init() {
$this->oMapperTopic=Engine::GetMapper(__CLASS__);
$this->oUserCurrent=$this->User_GetUserCurrent();
$aTopicTypeItems=$this->GetTopicTypeItems(array('state'=>self::TOPIC_TYPE_STATE_ACTIVE));
foreach($aTopicTypeItems as $oTypeItem) {
$this->aTopicTypes[$oTypeItem->getCode()]=$oTypeItem;
}
}
/**
* Возвращает список типов топика
* Возвращает список типов топика, возвращаются только активные типы
*
* @param bool $bOnlyCode Вернуть только коды типов
*
* @return array
*/
public function GetTopicTypes() {
return $this->aTopicTypes;
}
/**
* Добавляет в новый тип топика
*
* @param string $sType Новый тип
* @return bool
*/
public function AddTopicType($sType) {
if (!in_array($sType,$this->aTopicTypes)) {
$this->aTopicTypes[]=$sType;
return true;
}
return false;
public function GetTopicTypes($bOnlyCode=false) {
return $bOnlyCode ? array_keys($this->aTopicTypes) : $this->aTopicTypes;
}
/**
* Проверяет разрешен ли данный тип топика
@ -79,7 +77,7 @@ class ModuleTopic extends Module {
* @return bool
*/
public function IsAllowTopicType($sType) {
return in_array($sType,$this->aTopicTypes);
return array_key_exists($sType,$this->aTopicTypes);
}
/**
* Получает дополнительные данные(объекты) для топиков по их ID
@ -106,7 +104,6 @@ class ModuleTopic extends Module {
$aUserId=array();
$aBlogId=array();
$aTopicIdQuestion=array();
$aPhotoMainId=array();
foreach ($aTopics as $oTopic) {
if (isset($aAllowData['user'])) {
$aUserId[]=$oTopic->getUserId();
@ -117,9 +114,6 @@ class ModuleTopic extends Module {
if ($oTopic->getType()=='question') {
$aTopicIdQuestion[]=$oTopic->getId();
}
if ($oTopic->getType()=='photoset' and $oTopic->getPhotosetMainPhotoId()) {
$aPhotoMainId[]=$oTopic->getPhotosetMainPhotoId();
}
}
/**
* Получаем дополнительные данные
@ -140,7 +134,6 @@ class ModuleTopic extends Module {
if (isset($aAllowData['comment_new']) and $this->oUserCurrent) {
$aTopicsRead=$this->GetTopicsReadByArray($aTopicId,$this->oUserCurrent->getId());
}
$aPhotosetMainPhotos=$this->GetTopicPhotosByArrayId($aPhotoMainId);
/**
* Добавляем данные к результату - списку топиков
*/
@ -177,11 +170,6 @@ class ModuleTopic extends Module {
$oTopic->setCountCommentNew(0);
$oTopic->setDateRead(date("Y-m-d H:i:s"));
}
if (isset($aPhotosetMainPhotos[$oTopic->getPhotosetMainPhotoId()])) {
$oTopic->setPhotosetMainPhoto($aPhotosetMainPhotos[$oTopic->getPhotosetMainPhotoId()]);
} else {
$oTopic->setPhotosetMainPhoto(null);
}
}
return $aTopics;
}
@ -205,6 +193,13 @@ class ModuleTopic extends Module {
$this->AddTopicTag($oTag);
}
}
/**
* Обновляем дополнительные поля
* Здесь важный момент - перед сохранением топика всегда нужно вызывать валидацию полей $this->Property_ValidateEntityPropertiesCheck($oTopic);
* т.к. она подготавливает данные полей для сохранений
* Валидация вызывается автоматически при вызове $oTopic->_Validate();
*/
$this->Property_UpdatePropertiesValue($oTopic->getPropertiesObject(),$oTopic);
//чистим зависимые кеши
$this->Cache_Clean(Zend_Cache::CLEANING_MODE_MATCHING_TAG,array('topic_new',"topic_update_user_{$oTopic->getUserId()}","topic_new_blog_{$oTopic->getBlogId()}"));
return $oTopic;
@ -243,20 +238,20 @@ class ModuleTopic extends Module {
} else {
$sTopicId=$oTopicId;
}
/**
* Удаляем дополнительные поля
*/
$this->Property_RemovePropertiesValue(($oTopicId instanceof ModuleTopic_EntityTopic) ? $oTopicId : $this->GetTopicById($oTopicId));
/**
* Чистим зависимые кеши
*/
$this->Cache_Clean(Zend_Cache::CLEANING_MODE_MATCHING_TAG,array('topic_update'));
$this->Cache_Delete("topic_{$sTopicId}");
/**
* Список изображений
*/
$aPhotos=$this->getPhotosByTopicId($sTopicId);
/**
* Если топик успешно удален, удаляем связанные данные
*/
if($this->oMapperTopic->DeleteTopic($sTopicId)){
return $this->DeleteTopicAdditionalData($sTopicId,$aPhotos);
return $this->DeleteTopicAdditionalData($sTopicId);
}
return false;
@ -267,7 +262,7 @@ class ModuleTopic extends Module {
* @param int $iTopicId ID топика
* @return bool
*/
public function DeleteTopicAdditionalData($iTopicId,$aPhotos=array()) {
public function DeleteTopicAdditionalData($iTopicId) {
/**
* Чистим зависимые кеши
*/
@ -298,14 +293,6 @@ class ModuleTopic extends Module {
* Удаляем теги
*/
$this->DeleteTopicTagsByTopicId($iTopicId);
/**
* Удаляем фото у топика фотосета
*/
if (count($aPhotos)) {
foreach ($aPhotos as $oPhoto) {
$this->deleteTopicPhoto($oPhoto);
}
}
return true;
}
/**
@ -357,6 +344,13 @@ class ModuleTopic extends Module {
*/
$this->Comment_SetCommentsPublish($oTopic->getId(),'topic',$oTopic->getPublish());
}
/**
* Обновляем дополнительные поля
* Здесь важный момент - перед сохранением топика всегда нужно вызывать валидацию полей $this->Property_ValidateEntityPropertiesCheck($oTopic);
* т.к. она подготавливает данные полей для сохранений
* Валидация вызывается автоматически при вызове $oTopic->_Validate();
*/
$this->Property_UpdatePropertiesValue($oTopic->getPropertiesObject(),$oTopic);
//чистим зависимые кеши
$this->Cache_Clean(Zend_Cache::CLEANING_MODE_MATCHING_TAG,array('topic_update',"topic_update_user_{$oTopic->getUserId()}"));
$this->Cache_Delete("topic_{$oTopic->getId()}");
@ -1560,278 +1554,6 @@ class ModuleTopic extends Module {
}
return false;
}
/**
* Загрузка изображений при написании топика
*
* @param array $aFile Массив $_FILES
* @param ModuleUser_EntityUser $oUser Объект пользователя
* @return string|bool
*/
public function UploadTopicImageFile($aFile,$oUser) {
if(!is_array($aFile) || !isset($aFile['tmp_name'])) {
return false;
}
$sFileTmp=Config::Get('sys.cache.dir').func_generator();
if (!move_uploaded_file($aFile['tmp_name'],$sFileTmp)) {
return false;
}
$sDirUpload=$this->Image_GetIdDir($oUser->getId());
$aParams=$this->Image_BuildParams('topic');
if ($sFileImage=$this->Image_Resize($sFileTmp,$sDirUpload,func_generator(6),Config::Get('view.img_max_width'),Config::Get('view.img_max_height'),Config::Get('view.img_resize_width'),null,true,$aParams)) {
@unlink($sFileTmp);
return $this->Image_GetWebPath($sFileImage);
}
@unlink($sFileTmp);
return false;
}
/**
* Загрузка изображений по переданному URL
*
* @param string $sUrl URL изображения
* @param ModuleUser_EntityUser $oUser
* @return string|int
*/
public function UploadTopicImageUrl($sUrl, $oUser) {
/**
* Проверяем, является ли файл изображением
*/
if(!@getimagesize($sUrl)) {
return ModuleImage::UPLOAD_IMAGE_ERROR_TYPE;
}
/**
* Открываем файловый поток и считываем файл поблочно,
* контролируя максимальный размер изображения
*/
$oFile=fopen($sUrl,'r');
if(!$oFile) {
return ModuleImage::UPLOAD_IMAGE_ERROR_READ;
}
$iMaxSizeKb=Config::Get('view.img_max_size_url');
$iSizeKb=0;
$sContent='';
while (!feof($oFile) and $iSizeKb<$iMaxSizeKb) {
$sContent.=fread($oFile ,1024*1);
$iSizeKb++;
}
/**
* Если конец файла не достигнут,
* значит файл имеет недопустимый размер
*/
if(!feof($oFile)) {
return ModuleImage::UPLOAD_IMAGE_ERROR_SIZE;
}
fclose($oFile);
/**
* Создаем tmp-файл, для временного хранения изображения
*/
$sFileTmp=Config::Get('sys.cache.dir').func_generator();
$fp=fopen($sFileTmp,'w');
fwrite($fp,$sContent);
fclose($fp);
$sDirSave=$this->Image_GetIdDir($oUser->getId());
$aParams=$this->Image_BuildParams('topic');
/**
* Передаем изображение на обработку
*/
if ($sFileImg=$this->Image_Resize($sFileTmp,$sDirSave,func_generator(),Config::Get('view.img_max_width'),Config::Get('view.img_max_height'),Config::Get('view.img_resize_width'),null,true,$aParams)) {
@unlink($sFileTmp);
return $this->Image_GetWebPath($sFileImg);
}
@unlink($sFileTmp);
return ModuleImage::UPLOAD_IMAGE_ERROR;
}
/**
* Возвращает список фотографий к топику-фотосет по списку id фоток
*
* @param array $aPhotoId Список ID фото
* @return array
*/
public function GetTopicPhotosByArrayId($aPhotoId) {
if (!$aPhotoId) {
return array();
}
if (!is_array($aPhotoId)) {
$aPhotoId=array($aPhotoId);
}
$aPhotoId=array_unique($aPhotoId);
$aPhotos=array();
$s=join(',',$aPhotoId);
if (false === ($data = $this->Cache_Get("photoset_photo_id_{$s}"))) {
$data = $this->oMapperTopic->GetTopicPhotosByArrayId($aPhotoId);
foreach ($data as $oPhoto) {
$aPhotos[$oPhoto->getId()]=$oPhoto;
}
$this->Cache_Set($aPhotos, "photoset_photo_id_{$s}", array("photoset_photo_update"), 60*60*24*1);
return $aPhotos;
}
return $data;
}
/**
* Добавить к топику изображение
*
* @param ModuleTopic_EntityTopicPhoto $oPhoto Объект фото к топику-фотосету
* @return ModuleTopic_EntityTopicPhoto|bool
*/
public function addTopicPhoto($oPhoto) {
if ($sId=$this->oMapperTopic->addTopicPhoto($oPhoto)) {
$oPhoto->setId($sId);
$this->Cache_Clean(Zend_Cache::CLEANING_MODE_MATCHING_TAG,array("photoset_photo_update"));
return $oPhoto;
}
return false;
}
/**
* Получить изображение из фотосета по его id
*
* @param int $sId ID фото
* @return ModuleTopic_EntityTopicPhoto|null
*/
public function getTopicPhotoById($sId) {
$aPhotos=$this->GetTopicPhotosByArrayId($sId);
if (isset($aPhotos[$sId])) {
return $aPhotos[$sId];
}
return null;
}
/**
* Получить список изображений из фотосета по id топика
*
* @param int $iTopicId ID топика
* @param int|null $iFromId ID с которого начинать выборку
* @param int|null $iCount Количество
* @return array
*/
public function getPhotosByTopicId($iTopicId, $iFromId = null, $iCount = null) {
return $this->oMapperTopic->getPhotosByTopicId($iTopicId, $iFromId, $iCount);
}
/**
* Получить список изображений из фотосета по временному коду
*
* @param string $sTargetTmp Временный ключ
* @return array
*/
public function getPhotosByTargetTmp($sTargetTmp) {
return $this->oMapperTopic->getPhotosByTargetTmp($sTargetTmp);
}
/**
* Получить число изображений из фотосета по id топика
*
* @param int $iTopicId ID топика
* @return int
*/
public function getCountPhotosByTopicId($iTopicId) {
return $this->oMapperTopic->getCountPhotosByTopicId($iTopicId);
}
/**
* Получить число изображений из фотосета по id топика
*
* @param string $sTargetTmp Временный ключ
* @return int
*/
public function getCountPhotosByTargetTmp($sTargetTmp) {
return $this->oMapperTopic->getCountPhotosByTargetTmp($sTargetTmp);
}
/**
* Обновить данные по изображению
*
* @param ModuleTopic_EntityTopicPhoto $oPhoto Объект фото
*/
public function updateTopicPhoto($oPhoto) {
$this->Cache_Clean(Zend_Cache::CLEANING_MODE_MATCHING_TAG,array("photoset_photo_update"));
$this->oMapperTopic->updateTopicPhoto($oPhoto);
}
/**
* Удалить изображение
*
* @param ModuleTopic_EntityTopicPhoto $oPhoto Объект фото
*/
public function deleteTopicPhoto($oPhoto) {
$this->Cache_Clean(Zend_Cache::CLEANING_MODE_MATCHING_TAG,array("photoset_photo_update"));
$this->oMapperTopic->deleteTopicPhoto($oPhoto->getId());
$this->Image_RemoveFile($this->Image_GetServerPath($oPhoto->getWebPath()));
$aSizes=Config::Get('module.topic.photoset.size');
// Удаляем все сгенерированные миниатюры основываясь на данных из конфига.
foreach ($aSizes as $aSize) {
$sSize = $aSize['w'];
if ($aSize['crop']) {
$sSize .= 'crop';
}
$this->Image_RemoveFile($this->Image_GetServerPath($oPhoto->getWebPath($sSize)));
}
}
/**
* Загрузить изображение
*
* @param array $aFile Массив $_FILES
* @return string|bool
*/
public function UploadTopicPhoto($aFile) {
if(!is_array($aFile) || !isset($aFile['tmp_name'])) {
return false;
}
$sFileName = func_generator(10);
$sPath = Config::Get('path.uploads.images').'/topic/'.date('Y/m/d').'/';
if (!is_dir(Config::Get('path.root.server').$sPath)) {
mkdir(Config::Get('path.root.server').$sPath, 0755, true);
}
$sFileTmp = Config::Get('path.root.server').$sPath.$sFileName;
if (!move_uploaded_file($aFile['tmp_name'],$sFileTmp)) {
return false;
}
$aParams=$this->Image_BuildParams('photoset');
$oImage =$this->Image_CreateImageObject($sFileTmp);
/**
* Если объект изображения не создан,
* возвращаем ошибку
*/
if($sError=$oImage->get_last_error()) {
// Вывод сообщения об ошибки, произошедшей при создании объекта изображения
$this->Message_AddError($sError,$this->Lang_Get('error'));
@unlink($sFileTmp);
return false;
}
/**
* Превышает максимальные размеры из конфига
*/
if (($oImage->get_image_params('width')>Config::Get('view.img_max_width')) or ($oImage->get_image_params('height')>Config::Get('view.img_max_height'))) {
$this->Message_AddError($this->Lang_Get('topic_photoset_error_size'),$this->Lang_Get('error'));
@unlink($sFileTmp);
return false;
}
/**
* Добавляем к загруженному файлу расширение
*/
$sFile=$sFileTmp.'.'.$oImage->get_image_params('format');
rename($sFileTmp,$sFile);
$aSizes=Config::Get('module.topic.photoset.size');
foreach ($aSizes as $aSize) {
/**
* Для каждого указанного в конфиге размера генерируем картинку
*/
$sNewFileName = $sFileName.'_'.$aSize['w'];
$oImage = $this->Image_CreateImageObject($sFile);
if ($aSize['crop']) {
$this->Image_CropProportion($oImage, $aSize['w'], $aSize['h'], true);
$sNewFileName .= 'crop';
}
$this->Image_Resize($sFile,$sPath,$sNewFileName,Config::Get('view.img_max_width'),Config::Get('view.img_max_height'),$aSize['w'],$aSize['h'],true,$aParams,$oImage);
}
return $this->Image_GetWebPath($sFile);
}
/**
* Пересчитывает счетчик избранных топиков
*
@ -1871,5 +1593,38 @@ class ModuleTopic extends Module {
$this->Text_RemoveParams(array('oTopic'));
return $sResult;
}
}
?>
/**
* Возвращает объект типа топика по его коду
*
* @param string $sCode
*
* @return ModuleTopic_EntityTopicType|null
*/
public function GetTopicTypeByCode($sCode) {
return $this->oMapperTopic->GetTopicTypeByCode($sCode);
}
/**
* Добавляет новый тип топика в БД
*
* @param ModuleTopic_EntityTopicType $oType
*
* @return ModuleTopic_EntityTopicType|bool
*/
public function AddTopicType($oType) {
if ($sId=$this->oMapperTopic->AddTopicType($oType)) {
$oType->setId($sId);
//чистим зависимые кеши
$this->Cache_Clean(Zend_Cache::CLEANING_MODE_MATCHING_TAG,array('topic_type_new'));
return $oType;
}
return false;
}
/**
* @param array $aFilter
*
* @return mixed
*/
public function GetTopicTypeItems($aFilter=array()) {
return $this->oMapperTopic->GetTopicTypeItems($aFilter);
}
}

View file

@ -34,16 +34,12 @@ class ModuleTopic_EntityTopic extends Entity {
*/
public function Init() {
parent::Init();
$this->aValidateRules[]=array('topic_title','string','max'=>200,'min'=>2,'allowEmpty'=>false,'label'=>$this->Lang_Get('topic_create_title'),'on'=>array('topic','link','photoset'));
$this->aValidateRules[]=array('topic_title','string','max'=>200,'min'=>2,'allowEmpty'=>false,'label'=>$this->Lang_Get('topic_question_create_title'),'on'=>array('question'));
$this->aValidateRules[]=array('topic_text_source','string','max'=>Config::Get('module.topic.max_length'),'min'=>2,'allowEmpty'=>false,'label'=>$this->Lang_Get('topic_create_text'),'on'=>array('topic','photoset'));
$this->aValidateRules[]=array('topic_text_source','string','max'=>Config::Get('module.topic.link_max_length'),'min'=>10,'allowEmpty'=>false,'label'=>$this->Lang_Get('topic_create_text'),'on'=>array('link'));
$this->aValidateRules[]=array('topic_text_source','string','max'=>Config::Get('module.topic.question_max_length'),'allowEmpty'=>true,'label'=>$this->Lang_Get('topic_create_text'),'on'=>array('question'));
$this->aValidateRules[]=array('topic_tags','tags','count'=>15,'label'=>$this->Lang_Get('topic_create_tags'),'allowEmpty'=>Config::Get('module.topic.allow_empty_tags'),'on'=>array('topic','link','question','photoset'));
$this->aValidateRules[]=array('blog_id','blog_id','on'=>array('topic','link','question','photoset'));
$this->aValidateRules[]=array('topic_text_source','topic_unique','on'=>array('topic','link','question','photoset'));
$this->aValidateRules[]=array('topic_type','topic_type','on'=>array('topic','link','question','photoset'));
$this->aValidateRules[]=array('link_url','url','allowEmpty'=>false,'label'=>$this->Lang_Get('topic_link_create_url'),'on'=>array('link'));
$this->aValidateRules[]=array('topic_title','string','max'=>200,'min'=>2,'allowEmpty'=>false,'label'=>$this->Lang_Get('topic_create_title'));
$this->aValidateRules[]=array('topic_text_source','string','max'=>Config::Get('module.topic.max_length'),'min'=>2,'allowEmpty'=>false,'label'=>$this->Lang_Get('topic_create_text'));
$this->aValidateRules[]=array('topic_tags','tags','count'=>15,'label'=>$this->Lang_Get('topic_create_tags'),'allowEmpty'=>Config::Get('module.topic.allow_empty_tags'));
$this->aValidateRules[]=array('blog_id','blog_id');
$this->aValidateRules[]=array('topic_text_source','topic_unique');
}
/**
* Проверка типа топика
@ -83,10 +79,14 @@ class ModuleTopic_EntityTopic extends Entity {
* @return bool|string
*/
public function ValidateBlogId($sValue,$aParams) {
if ($sValue==0) {
if ($sValue==0 and $oBlog=$this->Blog_GetPersonalBlogByUserId($this->getUserId())) {
$this->setBlog($oBlog);
$this->setBlogId($oBlog->getId());
return true; // персональный блог
}
if ($this->Blog_GetBlogById((string)$sValue)) {
if ($oBlog=$this->Blog_GetBlogById((int)$sValue)) {
$this->setBlog($oBlog);
$this->setBlogId($oBlog->getId());
return true;
}
return $this->Lang_Get('topic_create_blog_error_unknown');
@ -365,7 +365,15 @@ class ModuleTopic_EntityTopic extends Entity {
* @return string
*/
public function getUrlEdit() {
return Router::GetPath($this->getType()).'edit/'.$this->getId().'/';
return Router::GetPath('content').'edit/'.$this->getId().'/';
}
/**
* Возвращает полный URL для удаления топика
*
* @return string
*/
public function getUrlDelete() {
return Router::GetPath('content').'delete/'.$this->getId().'/';
}
/**
* Возвращает объект голосования за топик текущим пользователем
@ -446,6 +454,15 @@ class ModuleTopic_EntityTopic extends Entity {
}
return $this->Subscribe_GetSubscribeByTargetAndMail('topic_new_comment',$this->getId(),$oUserCurrent->getMail());
}
/**
* Возвращает тип объекта для дополнительных полей
* Метод необходим для интеграции с дополнительными полями (модуль Property)
*
* @return string
*/
public function getPropertyTargetType() {
return 'topic_'.$this->getType();
}
/***************************************************************************************************************************************************
* методы расширения типов топика
@ -685,49 +702,6 @@ class ModuleTopic_EntityTopic extends Entity {
$this->setExtraValue('count_vote_abstain',$data);
}
/**
* Возвращает фотографии из топика-фотосета
*
* @param int|null $iFromId ID с которого начинать выборку
* @param int|null $iCount Количество
* @return array
*/
public function getPhotosetPhotos($iFromId = null, $iCount = null) {
return $this->Topic_getPhotosByTopicId($this->getId(), $iFromId, $iCount);
}
/**
* Возвращает количество фотографий в топике-фотосете
*
* @return int|null
*/
public function getPhotosetCount() {
return $this->getExtraValue('count_photo');
}
/**
* Возвращает ID главной фото в топике-фотосете
*
* @return int|null
*/
public function getPhotosetMainPhotoId() {
return $this->getExtraValue('main_photo_id');
}
/**
* Устанавливает ID главной фото в топике-фотосете
*
* @param int $data
*/
public function setPhotosetMainPhotoId($data) {
$this->setExtraValue('main_photo_id',$data);
}
/**
* Устанавливает количество фотографий в топике-фотосете
*
* @param int $data
*/
public function setPhotosetCount($data) {
$this->setExtraValue('count_photo',$data);
}
//*************************************************************************************************************************************************

View file

@ -1,108 +0,0 @@
<?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 modules.topic
* @since 1.0
*/
class ModuleTopic_EntityTopicPhoto extends Entity {
/**
* Возвращает ID фото
*
* @return int|null
*/
public function getId() {
return $this->_getDataOne('id');
}
/**
* Возвращает ID топика
*
* @return int|null
*/
public function getTopicId() {
return $this->_getDataOne('topic_id');
}
/**
* Возвращает ключ временного владельца
*
* @return string|null
*/
public function getTargetTmp() {
return $this->_getDataOne('target_tmp');
}
/**
* Возвращает описание фото
*
* @return string|null
*/
public function getDescription() {
return $this->_getDataOne('description');
}
/**
* Вовзращает полный веб путь до фото
*
* @return mixed|null
*/
public function getPath() {
return $this->_getDataOne('path');
}
/**
* Возвращает полный веб путь до фото определенного размера
*
* @param string|null $sWidth Размер фото, например, '100' или '150crop'
* @return null|string
*/
public function getWebPath($sWidth = null) {
if ($this->getPath()) {
if ($sWidth) {
$aPathInfo=pathinfo($this->getPath());
return $aPathInfo['dirname'].'/'.$aPathInfo['filename'].'_'.$sWidth.'.'.$aPathInfo['extension'];
} else {
return $this->getPath();
}
} else {
return null;
}
}
/**
* Устанавливает ID топика
*
* @param int $iTopicId
*/
public function setTopicId($iTopicId) {
$this->_aData['topic_id'] = $iTopicId;
}
/**
* Устанавливает ключ временного владельца
*
* @param string $sTargetTmp
*/
public function setTargetTmp($sTargetTmp) {
$this->_aData['target_tmp'] = $sTargetTmp;
}
/**
* Устанавливает описание фото
*
* @param string $sDescription
*/
public function setDescription($sDescription) {
$this->_aData['description'] = $sDescription;
}
}

View file

@ -0,0 +1,90 @@
<?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>
*
*/
/**
* Объект типа топика
* TODO: при удалении типа топика необходимо удалять дополнительные поля
*
* @package modules.topic
* @since 1.0
*/
class ModuleTopic_EntityTopicType extends Entity {
protected $aValidateRules=array(
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'),
);
public function ValidateCodeUnique() {
if ($oType=$this->Topic_GetTopicTypeByCode($this->getCode())) {
if ($oType->getId()!=$this->getId()) {
return 'Тип с таким кодом уже существует';
}
}
return true;
}
/**
* Возвращает список дополнительных параметров типа
*
* @return array|mixed
*/
public function getParamsArray() {
$aData=@unserialize($this->_getDataOne('params'));
if (!$aData) {
$aData=array();
}
return $aData;
}
/**
* Устанавливает список дополнительных параметров типа
*
* @param array $aParams
*/
public function setParams($aParams) {
$this->_aData['params']=@serialize($aParams);
}
/**
* Возвращает конкретный параметр типа
*
* @param string $sName
*
* @return null
*/
public function getParam($sName) {
$aParams=$this->getParams();
return isset($aParams[$sName]) ? $aParams[$sName] : null;
}
public function getStateText() {
if ($this->getState()==ModuleTopic::TOPIC_TYPE_STATE_ACTIVE) {
return 'активен';
}
if ($this->getState()==ModuleTopic::TOPIC_TYPE_STATE_NOT_ACTIVE) {
return 'не активен';
}
return 'неизвестный статус';
}
public function getUrlForAdd() {
return Router::GetPath('content/add').$this->getCode().'/';
}
}

View file

@ -813,143 +813,6 @@ class ModuleTopic_MapperTopic extends Mapper {
$res=$this->oDb->query($sql,$sBlogId,$aTopics);
return $res===false or is_null($res) ? false : true;
}
/**
* Возвращает список фотографий к топику-фотосет по списку id фоток
*
* @param array $aPhotoId Список ID фото
* @return array
*/
public function GetTopicPhotosByArrayId($aArrayId) {
if (!is_array($aArrayId) or count($aArrayId)==0) {
return array();
}
$sql = "SELECT
*
FROM
".Config::Get('db.table.topic_photo')."
WHERE
id IN(?a)
ORDER BY FIELD(id,?a) ";
$aReturn=array();
if ($aRows=$this->oDb->select($sql,$aArrayId,$aArrayId)) {
foreach ($aRows as $aPhoto) {
$aReturn[]=Engine::GetEntity('Topic_TopicPhoto',$aPhoto);
}
}
return $aReturn;
}
/**
* Получить список изображений из фотосета по id топика
*
* @param int $iTopicId ID топика
* @param int|null $iFromId ID с которого начинать выборку
* @param int|null $iCount Количество
* @return array
*/
public function getPhotosByTopicId($iTopicId, $iFromId, $iCount) {
$sql = 'SELECT * FROM ' . Config::Get('db.table.topic_photo') . ' WHERE topic_id = ?d {AND id > ?d LIMIT 0, ?d}';
$aPhotos = $this->oDb->select($sql, $iTopicId, ($iFromId !== null) ? $iFromId : DBSIMPLE_SKIP, $iCount);
$aReturn = array();
if (is_array($aPhotos) && count($aPhotos)) {
foreach($aPhotos as $aPhoto) {
$aReturn[] = Engine::GetEntity('Topic_TopicPhoto', $aPhoto);
}
}
return $aReturn;
}
/**
* Получить список изображений из фотосета по временному коду
*
* @param string $sTargetTmp Временный ключ
* @return array
*/
public function getPhotosByTargetTmp($sTargetTmp) {
$sql = 'SELECT * FROM ' . Config::Get('db.table.topic_photo') . ' WHERE target_tmp = ?';
$aPhotos = $this->oDb->select($sql, $sTargetTmp);
$aReturn = array();
if (is_array($aPhotos) && count($aPhotos)) {
foreach($aPhotos as $aPhoto) {
$aReturn[] = Engine::GetEntity('Topic_TopicPhoto', $aPhoto);
}
}
return $aReturn;
}
/**
* Получить изображение из фотосета по его id
*
* @param int $iPhotoId ID фото
* @return ModuleTopic_EntityTopicPhoto|null
*/
public function getTopicPhotoById($iPhotoId) {
$sql = 'SELECT * FROM ' . Config::Get('db.table.topic_photo') . ' WHERE id = ?d';
$aPhoto = $this->oDb->selectRow($sql, $iPhotoId);
if ($aPhoto) {
return Engine::GetEntity('Topic_TopicPhoto', $aPhoto);
} else {
return null;
}
}
/**
* Получить число изображений из фотосета по id топика
*
* @param int $iTopicId ID топика
* @return int
*/
public function getCountPhotosByTopicId($iTopicId) {
$sql = 'SELECT count(id) FROM ' . Config::Get('db.table.topic_photo') . ' WHERE topic_id = ?d';
$aPhotosCount = $this->oDb->selectCol($sql, $iTopicId);
return $aPhotosCount[0];
}
/**
* Получить число изображений из фотосета по id топика
*
* @param string $sTargetTmp Временный ключ
* @return int
*/
public function getCountPhotosByTargetTmp($sTargetTmp) {
$sql = 'SELECT count(id) FROM ' . Config::Get('db.table.topic_photo') . ' WHERE target_tmp = ?';
$aPhotosCount = $this->oDb->selectCol($sql, $sTargetTmp);
return $aPhotosCount[0];
}
/**
* Добавить к топику изображение
*
* @param ModuleTopic_EntityTopicPhoto $oPhoto Объект фото к топику-фотосету
* @return bool
*/
public function addTopicPhoto($oPhoto) {
if (!$oPhoto->getTopicId() && !$oPhoto->getTargetTmp()) return false;
$sTargetType = ($oPhoto->getTopicId()) ? 'topic_id' : 'target_tmp';
$iTargetId = ($sTargetType == 'topic_id') ? $oPhoto->getTopicId() : $oPhoto->getTargetTmp();
$sql = 'INSERT INTO '. Config::Get('db.table.topic_photo') . ' SET
path = ?, description = ?, ?# = ?';
return $this->oDb->query($sql, $oPhoto->getPath(), $oPhoto->getDescription(), $sTargetType, $iTargetId);
}
/**
* Обновить данные по изображению
*
* @param ModuleTopic_EntityTopicPhoto $oPhoto Объект фото
*/
public function updateTopicPhoto($oPhoto) {
if (!$oPhoto->getTopicId() && !$oPhoto->getTargetTmp()) return false;
if ($oPhoto->getTopicId()) {
$oPhoto->setTargetTmp = null;
}
$sql = 'UPDATE '. Config::Get('db.table.topic_photo') . ' SET
path = ?, description = ?, topic_id = ?d, target_tmp=? WHERE id = ?d';
$this->oDb->query($sql, $oPhoto->getPath(), $oPhoto->getDescription(), $oPhoto->getTopicId(), $oPhoto->getTargetTmp(), $oPhoto->getId());
}
/**
* Удалить изображение
*
* @param int $iPhotoId ID фото
*/
public function deleteTopicPhoto($iPhotoId) {
$sql = 'DELETE FROM '. Config::Get('db.table.topic_photo') . ' WHERE
id= ?d';
$this->oDb->query($sql, $iPhotoId);
}
/**
* Пересчитывает счетчик избранных топиков
*
@ -1012,5 +875,51 @@ class ModuleTopic_MapperTopic extends Mapper {
$res=$this->oDb->query($sql);
return $res===false or is_null($res) ? false : true;
}
}
?>
public function GetTopicTypeByCode($sCode) {
$sql = 'SELECT * FROM ' . Config::Get('db.table.topic_type') . ' WHERE code = ?';
if ($aRow = $this->oDb->selectRow($sql, $sCode)) {
return Engine::GetEntity('ModuleTopic_EntityTopicType',$aRow);
}
return null;
}
public function AddTopicType($oType) {
$sql = "INSERT INTO ".Config::Get('db.table.topic_type')."
(name,
name_many,
code,
allow_remove,
date_create,
state,
params
)
VALUES(?, ?, ?, ?d, ?, ?d, ?)
";
if ($iId=$this->oDb->query($sql,$oType->getName(),$oType->getNameMany(),$oType->getCode(),$oType->getAllowRemove(),
$oType->getDateCreate(),$oType->getState(),$oType->getParams())) {
return $iId;
}
return false;
}
public function GetTopicTypeItems($aFilter=array()) {
$sql = "SELECT
*
FROM
".Config::Get('db.table.topic_type')."
WHERE
1 = 1
{ and state = ?d }
LIMIT 0, 500
";
$aReturn=array();
if ($aRows=$this->oDb->select($sql,isset($aFilter['state']) ? $aFilter['state'] : DBSIMPLE_SKIP)) {
foreach ($aRows as $aRow) {
$aReturn[]=Engine::GetEntity('ModuleTopic_EntityTopicType',$aRow);
}
}
return $aReturn;
}
}

View file

@ -196,38 +196,6 @@ $config['module']['wall']['per_page'] = 10; // Число сообщени
$config['module']['wall']['text_max'] = 250; // Ограничение на максимальное количество символов в одном сообщении на стене
$config['module']['wall']['text_min'] = 1; // Ограничение на минимальное количество символов в одном сообщении на стене
/**
* Настройка топика-фотосета
*/
$config['module']['image']['photoset']['jpg_quality'] = 100; // настройка модуля Image, качество обработки фото
$config['module']['topic']['photoset']['photo_max_size'] = 6*1024; // максимально допустимый размер фото, Kb
$config['module']['topic']['photoset']['count_photos_min'] = 2; // минимальное количество фоток
$config['module']['topic']['photoset']['count_photos_max'] = 30; // максимальное количество фоток
$config['module']['topic']['photoset']['per_page'] = 20; // число фоток для одновременной загрузки
$config['module']['topic']['photoset']['size'] = array( // список размеров превью, которые необходимо делать при загрузке фото
array(
'w' => 1000,
'h' => null,
'crop' => false,
),
array(
'w' => 500,
'h' => null,
'crop' => false,
),
array(
'w' => 100,
'h' => 65,
'crop' => true,
),
array(
'w' => 50,
'h' => 50,
'crop' => true,
)
);
/**
* Модуль Media
*/
@ -275,9 +243,10 @@ $config['db']['table']['prefix'] = 'prefix_';
$config['db']['table']['user'] = '___db.table.prefix___user';
$config['db']['table']['blog'] = '___db.table.prefix___blog';
$config['db']['table']['blog_category'] = '___db.table.prefix___blog_category';
$config['db']['table']['blog_category'] = '___db.table.prefix___blog_category';
$config['db']['table']['topic'] = '___db.table.prefix___topic';
$config['db']['table']['topic_tag'] = '___db.table.prefix___topic_tag';
$config['db']['table']['topic_type'] = '___db.table.prefix___topic_type';
$config['db']['table']['comment'] = '___db.table.prefix___comment';
$config['db']['table']['vote'] = '___db.table.prefix___vote';
$config['db']['table']['topic_read'] = '___db.table.prefix___topic_read';
@ -303,7 +272,6 @@ $config['db']['table']['stream_event'] = '___db.table.prefix___stream_eve
$config['db']['table']['stream_user_type'] = '___db.table.prefix___stream_user_type';
$config['db']['table']['user_field'] = '___db.table.prefix___user_field';
$config['db']['table']['user_field_value'] = '___db.table.prefix___user_field_value';
$config['db']['table']['topic_photo'] = '___db.table.prefix___topic_photo';
$config['db']['table']['subscribe'] = '___db.table.prefix___subscribe';
$config['db']['table']['wall'] = '___db.table.prefix___wall';
$config['db']['table']['user_note'] = '___db.table.prefix___user_note';
@ -339,7 +307,6 @@ $config['router']['page']['my'] = 'ActionMy';
$config['router']['page']['blog'] = 'ActionBlog';
$config['router']['page']['personal_blog'] = 'ActionPersonalBlog';
$config['router']['page']['index'] = 'ActionIndex';
$config['router']['page']['topic'] = 'ActionTopic';
$config['router']['page']['login'] = 'ActionLogin';
$config['router']['page']['people'] = 'ActionPeople';
$config['router']['page']['settings'] = 'ActionSettings';
@ -347,16 +314,14 @@ $config['router']['page']['tag'] = 'ActionTag';
$config['router']['page']['talk'] = 'ActionTalk';
$config['router']['page']['comments'] = 'ActionComments';
$config['router']['page']['rss'] = 'ActionRss';
$config['router']['page']['link'] = 'ActionLink';
$config['router']['page']['question'] = 'ActionQuestion';
$config['router']['page']['blogs'] = 'ActionBlogs';
$config['router']['page']['search'] = 'ActionSearch';
$config['router']['page']['admin'] = 'ActionAdmin';
$config['router']['page']['ajax'] = 'ActionAjax';
$config['router']['page']['feed'] = 'ActionUserfeed';
$config['router']['page']['stream'] = 'ActionStream';
$config['router']['page']['photoset'] = 'ActionPhotoset';
$config['router']['page']['subscribe'] = 'ActionSubscribe';
$config['router']['page']['content'] = 'ActionContent';
// Глобальные настройки роутинга
$config['router']['config']['action_default'] = 'index';
$config['router']['config']['action_not_found'] = 'error';
@ -379,10 +344,7 @@ $config['block']['rule_index'] = array(
);
$config['block']['rule_topic_type'] = array(
'action' => array(
'link' => array('add','edit'),
'question' => array('add','edit'),
'topic' => array('add','edit'),
'photoset' => array('add','edit')
'content' => array('add','edit'),
),
'blocks' => array( 'right' => array('blocks/block.blogInfo.tpl', 'blocks/block.blogInfoNote.tpl') ),
);
@ -519,7 +481,6 @@ $config['head']['default']['js'] = array(
"___path.application.web___/frontend/common/js/user.js",
"___path.application.web___/frontend/common/js/userfeed.js",
"___path.application.web___/frontend/common/js/stream.js",
"___path.application.web___/frontend/common/js/photoset.js",
"___path.application.web___/frontend/common/js/toolbar.js",
"___path.application.web___/frontend/common/js/settings.js",
"___path.application.web___/frontend/common/js/topic.js",
@ -528,6 +489,7 @@ $config['head']['default']['js'] = array(
"___path.application.web___/frontend/common/js/captcha.js",
"___path.application.web___/frontend/common/js/media.js",
"___path.application.web___/frontend/common/js/tags.js",
"___path.application.web___/frontend/common/js/content.js",
"___path.application.web___/frontend/common/js/init.js",
"http://yandex.st/share/share.js" => array('merge'=>false),

View file

@ -0,0 +1,72 @@
/**
* Контент
*
* @module ls/content
*
* @license GNU General Public License, version 2
* @copyright 2013 OOO "ЛС-СОФТ" {@link http://livestreetcms.com}
* @author Denis Shakhov <denis.shakhov@gmail.com>
*/
var ls = ls || {};
ls.content = (function ($) {
"use strict";
/**
* Дефолтные опции
*/
var defaults = {
// Роутеры
routers: {
add: aRouter['content'] + 'ajax/add/',
edit: aRouter['content'] + 'ajax/edit/'
}
};
/**
* Инициализация
*
* @param {Object} options Опции
*/
this.init = function(options) {
this.options = $.extend({}, defaults, options);
$('#submit-add-topic-publish').on('click',function(){
ls.content.save('add','form-topic-add',{ 'submit_topic_publish': 1 });
});
$('#submit-add-topic-save').on('click',function(){
ls.content.save('add','form-topic-add',{ 'submit_topic_save': 1 });
});
$('#submit-edit-topic-publish').on('click',function(){
ls.content.save('edit','form-topic-add',{ 'submit_topic_publish': 1 });
});
$('#submit-edit-topic-save').on('click',function(){
ls.content.save('edit','form-topic-add',{ 'submit_topic_save': 1 });
});
};
/**
* Создание контента
*
* @param {String} sFormId ID формы
*/
this.save = function(submitType,sFormId,params) {
var oForm = $('#' + sFormId);
ls.ajax.submit(this.options.routers[submitType], oForm, function(result) {
if (result.bStateError) {
ls.msg.error(null, result.sMsg);
} else {
if (result.sUrlRedirect) {
window.location.href=result.sUrlRedirect;
}
}
},{ params: params });
return false;
};
return this;
}).call(ls.content || {}, jQuery);

View file

@ -1,187 +0,0 @@
/**
* Фотосет
*
* @module ls/photoset
*
* @license GNU General Public License, version 2
* @copyright 2013 OOO "ЛС-СОФТ" {@link http://livestreetcms.com}
* @author Denis Shakhov <denis.shakhov@gmail.com>
*/
var ls = ls || {};
ls.photoset =( function ($) {
this.idLast=0;
this.isLoading=false;
this.swfu;
/**
* Инициализация
*/
this.init = function() {
var self = this;
$('#js-photoset-image-upload').on('change', function (e) {
self.upload();
});
};
this.initSwfUpload = function(opt) {
opt=opt || {};
opt.button_placeholder_id = 'js-photoset-image-upload-flash';
opt.post_params.ls_photoset_target_tmp = $.cookie('ls_photoset_target_tmp') ? $.cookie('ls_photoset_target_tmp') : 0;
$(ls.swfupload).unbind('load').bind('load',function() {
this.swfu = ls.swfupload.init(opt);
$(this.swfu).bind('eUploadProgress',this.swfHandlerUploadProgress);
$(this.swfu).bind('eFileDialogComplete',this.swfHandlerFileDialogComplete);
$(this.swfu).bind('eUploadSuccess',this.swfHandlerUploadSuccess);
$(this.swfu).bind('eUploadComplete',this.swfHandlerUploadComplete);
}.bind(this));
ls.swfupload.loadSwf();
}
this.swfHandlerUploadProgress = function(e, file, bytesLoaded, percent) {
$('#photoset_photo_empty_filename').text(file.name);
$('#photoset_photo_empty_progress').find('.js-upload-label').text(percent >= 100 ? 'resize..' : percent +'%');
$('#photoset_photo_empty_progress').find('.js-upload-percents').css({ 'width' : percent + '%' });
}
this.swfHandlerFileDialogComplete = function(e, numFilesSelected, numFilesQueued) {
if (numFilesQueued>0) {
ls.photoset.addPhotoEmpty();
}
}
this.swfHandlerUploadSuccess = function(e, file, serverData) {
ls.photoset.addPhoto(jQuery.parseJSON(serverData));
}
this.swfHandlerUploadComplete = function(e, file, next) {
if (next>0) {
ls.photoset.addPhotoEmpty();
}
}
this.addPhotoEmpty = function() {
template = '<li id="photoset_photo_empty" class="photoset-upload-progress">' +
'<div id="photoset_photo_empty_filename" class="photoset-upload-progress-filename"></div>' +
'<div id="photoset_photo_empty_progress" class="progress-bar">' +
'<div class="progress-bar-value js-upload-percents"></div>' +
'<div class="progress-bar-label js-upload-label">Uploading...</div>' +
'</div>' +
'</li>';
$('#swfu_images').append(template);
}
this.addPhoto = function(response) {
$('#photoset_photo_empty').remove();
if (!response.bStateError) {
template = '<li id="photo_'+response.id+'" class="photoset-upload-images-item"><img src="'+response.file+'" alt="image" />'
+'<textarea onBlur="ls.photoset.setPreviewDescription('+response.id+', this.value)" class="width-full"></textarea><br />'
+'<a href="javascript:ls.photoset.deletePhoto('+response.id+')" class="link-dotted">'+ls.lang.get('topic_photoset_photo_delete')+'</a>'
+'<span id="photo_preview_state_'+response.id+'" class="photo-preview-state"><a href="javascript:ls.photoset.setPreview('+response.id+')" class="link-dotted mark-as-preview">'+ls.lang.get('topic_photoset_mark_as_preview')+'</a></span></li>';
$('#swfu_images').append(template);
} else {
ls.msg.error(response.sMsgTitle,response.sMsg);
}
$('#modal-photoset-upload').modal('hide');
}
this.deletePhoto = function(id)
{
if (!confirm(ls.lang.get('topic_photoset_photo_delete_confirm'))) {return;}
ls.ajax.load(aRouter['photoset']+'deleteimage', {'id':id}, function(response){
if (!response.bStateError) {
$('#photo_'+id).remove();
ls.msg.notice(response.sMsgTitle,response.sMsg);
} else {
ls.msg.error(response.sMsgTitle,response.sMsg);
}
});
}
this.setPreview =function(id)
{
$('#topic_main_photo').val(id);
$('.marked-as-preview').each(function (index, el) {
$(el).removeClass('marked-as-preview');
tmpId = $(el).attr('id').slice($(el).attr('id').lastIndexOf('_')+1);
$('#photo_preview_state_'+tmpId).html('<a href="javascript:ls.photoset.setPreview('+tmpId+')" class="mark-as-preview link-dotted">'+ls.lang.get('topic_photoset_mark_as_preview')+'</a>');
});
$('#photo_'+id).addClass('marked-as-preview');
$('#photo_preview_state_'+id).html(ls.lang.get('topic_photoset_is_preview'));
}
this.setPreviewDescription = function(id, text)
{
ls.ajax.load(aRouter['photoset']+'setimagedescription', {'id':id, 'text':text}, function(result){
if (!result.bStateError) {
} else {
ls.msg.error('Error','Please try again later');
}
}
)
}
this.getMore = function(topic_id)
{
if (this.isLoading) return;
this.isLoading=true;
ls.ajax.load(aRouter['photoset']+'getmore', {'topic_id':topic_id, 'last_id':this.idLast}, function(result){
this.isLoading=false;
if (!result.bStateError) {
if (result.photos) {
$.each(result.photos, function(index, photo) {
var image = '<li><a class="photoset-image" href="'+photo.path+'" rel="[photoset]" title="'+photo.description+'"><img src="'+photo.path_thumb+'" alt="'+photo.description+'" /></a></li>';
$('#topic-photo-images').append(image);
this.idLast=photo.id;
$('.photoset-image').unbind('click');
$('.photoset-image').prettyPhoto({
social_tools:'',
show_title: false,
slideshow:false,
deeplinking: false
});
}.bind(this));
}
if (!result.bHaveNext || !result.photos) {
$('#topic-photo-more').remove();
}
} else {
ls.msg.error('Error','Please try again later');
}
}.bind(this));
}
this.upload = function() {
ls.photoset.addPhotoEmpty();
var input = $('#js-photoset-image-upload');
var form = $('<form method="post" enctype="multipart/form-data">' +
'<input type="hidden" name="is_iframe" value="true" />' +
'<input type="hidden" name="topic_id" value="' + input.data('topic-id') + '" />' +
'</form>').hide().appendTo('body');
input.clone(true).insertAfter(input);
input.appendTo(form);
ls.ajax.submit(aRouter['photoset'] + 'upload/', form, function (data) {
if (data.bStateError) {
$('#photoset_photo_empty').remove();
ls.msg.error(data.sMsgTitle,data.sMsg);
} else {
ls.photoset.addPhoto(data);
}
form.remove();
});
}
return this;
}).call(ls.photoset || {},jQuery);

View file

@ -19,7 +19,7 @@ ls.topic = (function ($) {
var defaults = {
// Роутеры
oRouters: {
preview: aRouter['ajax'] + 'preview/topic/'
preview: aRouter['content'] + 'ajax/preview/'
},
// Селекторы

View file

@ -339,34 +339,6 @@ return array(
'topic_vote_ok' => 'Your vote counted',
'topic_vote_ok_abstain' => 'You\'ve abstained to view the topic rating',
'topic_vote_count' => 'all votes',
/**
* Photoset
*/
'topic_photoset_create' => 'Create a photoset',
'topic_photoset_edit' => 'Update a photoset',
'topic_photoset_upload_title' => 'Upload images',
'topic_photoset_upload_choose' => 'Upload photo',
'topic_photoset_upload_close' => 'Close',
'topic_photoset_upload_rules' => 'Image upload is available for JPG, PNG, GIF.<br/> Image size should not exceed %%SIZE%% Kb.<br /> Maximum number of images uploaded: %%COUNT%%',
'topic_photoset_choose_image' => 'Select the image to upload',
'topic_photoset_is_preview' => 'Marked as a topic preview',
'topic_photoset_mark_as_preview' => 'Mark as preview',
'topic_photoset_show_all' => 'Display all %%COUNT%% photos',
'topic_photoset_count_images' => 'image;images;images',
'topic_photoset_show_more' => 'View more photos',
'topic_photoset_error_count_photos' => 'There can be from %%MIN%% to %%MAX%% images in the topic ',
'topic_photoset_error_size' => 'The image resolution is too large',
'topic_photoset_title' => 'Photoset',
'topic_photoset_photo_deleted' => 'Photo removed',
'topic_photoset_photo_deleted_error_last' => 'You can not delete the last photo',
'topic_photoset_photo_delete' => 'Delete',
'topic_photoset_photo_delete_confirm' => 'Delete photo?',
'topic_photoset_photo_added' => 'Photo added',
'topic_photoset_error_too_much_photos' => 'Topic can contain no more than %%MAX%% photos',
'topic_photoset_title_edit' => 'Edit photoset',
'topic_photoset_title_create' => 'Create a photoset',
'topic_photoset_error_bad_filesize' => 'Photo size must be less than %%MAX%% Kb',
'topic_photoset_photos' => 'photos',
/**
* Comments
*/
@ -1059,6 +1031,7 @@ return array(
/**
* Validation
*/
'validate_empty_error' => 'Field %%field%% is required',
'validate_string_too_long' => 'Field %%field%% is too long (maximum is %%max%% characters).',
'validate_string_too_short' => 'Field %%field%% is too short (minimum is %%min%% characters)',
'validate_string_no_lenght' => 'Field %%field%% has the wrong length (should be %%length%% characters)',

View file

@ -339,34 +339,6 @@ return array(
'topic_vote_ok' => 'Ваш голос учтен',
'topic_vote_ok_abstain' => 'Вы воздержались для просмотра рейтинга топика',
'topic_vote_count' => 'всего проголосовало',
/**
* Фотосет
*/
'topic_photoset_create' => 'Создание фотосета',
'topic_photoset_edit' => 'Редактирование фотосета',
'topic_photoset_upload_title' => 'Загрузка изображений',
'topic_photoset_upload_choose' => 'Загрузить фото',
'topic_photoset_upload_close' => 'Закрыть',
'topic_photoset_upload_rules' => 'Доступна загрузка изображений в формат JPG, PNG, GIF<br />Размер изображений не должен превышать %%SIZE%% Kб<br />Максимальное число загружаемых изображений: %%COUNT%%',
'topic_photoset_choose_image' => 'Выберите изображение для загрузки',
'topic_photoset_is_preview' => 'Отмечено как превью к топику',
'topic_photoset_mark_as_preview' => 'Отметить как превью',
'topic_photoset_show_all' => 'Показать все %%COUNT%% фото',
'topic_photoset_count_images' => 'изображение;изображения;изображений',
'topic_photoset_show_more' => 'Показать ещё фото',
'topic_photoset_error_count_photos' => 'В топике может быть от %%MIN%% до %%MAX%% фото',
'topic_photoset_error_size' => 'У изображения слишком большое разрешение',
'topic_photoset_title' => 'Фотосет',
'topic_photoset_photo_deleted' => 'Фото удалено',
'topic_photoset_photo_deleted_error_last' => 'Нельзя удалить последню фотографию',
'topic_photoset_photo_delete' => 'Удалить',
'topic_photoset_photo_delete_confirm' => 'Удалить фото?',
'topic_photoset_photo_added' => 'Фото добавлено',
'topic_photoset_error_too_much_photos' => 'Топик может содержать не более %%MAX%% фото',
'topic_photoset_title_edit' => 'Редактирование фотосета',
'topic_photoset_title_create' => 'Создание фотосета',
'topic_photoset_error_bad_filesize' => 'Размер фото должен быть не более %%MAX%% Кб',
'topic_photoset_photos' => 'фото',
/**
* Комментарии
*/
@ -1060,6 +1032,7 @@ return array(
/**
* Валидация данных
*/
'validate_empty_error' => 'Необходимо заполнить поле %%field%%',
'validate_string_too_long' => 'Поле %%field%% слишком длинное (максимально допустимо %%max%% символов)',
'validate_string_too_short' => 'Поле %%field%% слишком короткое (минимально допустимо %%min%% символов)',
'validate_string_no_lenght' => 'Поле %%field%% неверной длины (необходимо %%length%% символов)',

View file

@ -0,0 +1,7 @@
{**
* Создание топика
*
* @styles css/topic.css
*}
{extends file='forms/form.add.content.tpl'}

View file

@ -1,15 +0,0 @@
{**
* Создание топика-ссылки
*
* @styles css/topic.css
*}
{extends file='forms/form.add.topic.base.tpl'}
{block name='add_topic_form_text_before'}
{include file='forms/fields/form.field.text.tpl'
sFieldName = 'topic_link_url'
sFieldRules = 'required="true" type="url"'
sFieldNote = $aLang.topic_link_create_url_notice
sFieldLabel = $aLang.topic_link_create_url}
{/block}

View file

@ -1,67 +0,0 @@
{**
* Создание топика-фотосета
*
* @styles css/topic.css
*}
{extends file='forms/form.add.topic.base.tpl'}
{block name='add_topic_type'}photoset{/block}
{block name='add_topic_form_text_after'}
<script type="text/javascript">
jQuery(function($){
if (jQuery.browser.flash) {
ls.photoset.initSwfUpload({
post_params: { 'topic_id': {json var=$_aRequest.topic_id} }
});
}
});
</script>
<div class="fieldset photoset-upload">
<header class="fieldset-header">
<h2 class="fieldset-title">{$aLang.topic_photoset_upload_title}</h2>
<div class="note fieldset-note">
{$aLang.topic_photoset_upload_rules|ls_lang:"SIZE%%`$oConfig->get('module.topic.photoset.photo_max_size')`":"COUNT%%`$oConfig->get('module.topic.photoset.count_photos_max')`"}
</div>
</header>
<ul class="fieldset-body photoset-upload-images" id="swfu_images">
{if count($aPhotos)}
{foreach $aPhotos as $oPhoto}
{if $_aRequest.topic_main_photo && $_aRequest.topic_main_photo == $oPhoto->getId()}
{$bIsMainPhoto = true}
{/if}
<li id="photo_{$oPhoto->getId()}" class="photoset-upload-images-item {if $bIsMainPhoto}marked-as-preview{/if}">
<img src="{$oPhoto->getWebPath('100crop')}" alt="image" />
<textarea onBlur="ls.photoset.setPreviewDescription({$oPhoto->getId()}, this.value)" class="width-full">{$oPhoto->getDescription()}</textarea><br />
<a href="javascript:ls.photoset.deletePhoto({$oPhoto->getId()})" class="link-dotted ">{$aLang.topic_photoset_photo_delete}</a>
<span id="photo_preview_state_{$oPhoto->getId()}" class="photo-preview-state">
{if $bIsMainPhoto}
{$aLang.topic_photoset_is_preview}
{else}
<a href="javascript:ls.photoset.setPreview({$oPhoto->getId()})" class="link-dotted mark-as-preview">{$aLang.topic_photoset_mark_as_preview}</a>
{/if}
</span>
</li>
{$bIsMainPhoto = false}
{/foreach}
{/if}
</ul>
<footer class="fieldset-footer">
{include file='forms/fields/form.field.hidden.tpl' sFieldName='topic_main_photo' value=$_aRequest.topic_main_photo}
<label class="form-input-file">
<span class="button" id="js-photoset-image-upload-flash">{$aLang.topic_photoset_upload_choose}</span>
<input type="file" name="Filedata" id="js-photoset-image-upload" data-topic-id="{$_aRequest.topic_id}">
</label>
</footer>
</div>
{/block}

View file

@ -1,42 +0,0 @@
{**
* Создание топика-опроса
*
* @styles css/topic.css
* @scripts <framework>/js/livestreet/poll.js
*}
{extends file='forms/form.add.topic.base.tpl'}
{block name='add_topic_type'}question{/block}
{block name='add_topic_form_text_before'}
<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">
{if count($_aRequest.answer) >= 2}
{foreach $_aRequest.answer as $sAnswer}
<li class="poll-add-item js-poll-add-item">
<input type="text" value="{$sAnswer}" name="answer[]" class="poll-add-item-input js-poll-add-item-input" {if $bEditDisabled}disabled{/if} />
{if ! $bEditDisabled and $sAnswer@key > 1}
<i class="icon-remove poll-add-item-remove js-poll-add-item-remove" title="{$aLang.topic_question_create_answers_delete}"></i>
{/if}
</li>
{/foreach}
{else}
<li class="poll-add-item js-poll-add-item"><input type="text" name="answer[]" class="poll-add-item-input js-poll-add-item-input" {if $bEditDisabled}disabled{/if} /></li>
<li class="poll-add-item js-poll-add-item"><input type="text" name="answer[]" class="poll-add-item-input js-poll-add-item-input" {if $bEditDisabled}disabled{/if} /></li>
{/if}
</ul>
{if ! $bEditDisabled}
<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>
{/block}

View file

@ -1,7 +0,0 @@
{**
* Создание обычного текстового топика
*
* @styles css/topic.css
*}
{extends file='forms/form.add.topic.base.tpl'}

View file

@ -1,44 +0,0 @@
/**
* Фотосет
*
* @license GNU General Public License, version 2
* @copyright 2013 OOO "ЛС-СОФТ" {@link http://livestreetcms.com}
* @author Denis Shakhov <denis.shakhov@gmail.com>
*/
.photoset { margin-bottom: 15px; }
/**
* Дефолтный фотосет
*
* @modifier default
* @template topics/topic.photoset.tpl
*/
.photoset-type-default { padding-top: 10px; }
.photoset-type-default .photoset-title { border-bottom: 1px solid #ddd; padding-bottom: 4px; margin-bottom: 15px; font-size: 16px; }
.photoset-type-default .photoset-images { overflow: hidden; zoom: 1; }
.photoset-type-default .photoset-images li { float: left; margin: 0 9px 9px 0; position: relative; border: 3px solid #eee; }
.photoset-type-default .photoset-images li img { vertical-align: top; }
/**
* Загрузка изображений
*
* @template actions/ActionPhotoset/add.tpl
*/
.photoset-upload .fieldset-body { padding: 0 0 15px; }
.photoset-upload-images { overflow: hidden; zoom: 1; }
.photoset-upload-images-item { padding: 15px 15px 15px 130px; min-height: 100px; position: relative; }
.photoset-upload-images-item.marked-as-preview { background: #eee; }
.photoset-upload-images-item img { position: absolute; top: 15px; left: 15px; }
.photoset-upload-images-item label { color: #aaa; }
.photoset-upload-images-item textarea { height: 80px; margin-bottom: 10px; }
.photoset-upload-images-item a { margin-right: 15px; }
.photoset-upload-images-item .mark-as-preview { display: none; text-decoration: none; }
.photoset-upload-images-item:hover .mark-as-preview { display: inline; }
.photoset-upload-progress { margin: 15px; }
.photoset-upload-progress-filename { margin-bottom: 5px; }

View file

@ -122,14 +122,6 @@
.topic .vote.vote-count-negative .vote-item { background: #DA3A3A; }
/**
* Топик фотосет
*
* @template topics/topic.photoset.tpl
*/
.topic.topic-type-photoset .topic-content { margin-bottom: 25px; }
/**
* Топик ссылка
*

View file

@ -175,6 +175,7 @@ jQuery(document).ready(function($){
* Topic
*/
ls.topic.init();
ls.content.init();
/**
@ -195,12 +196,6 @@ jQuery(document).ready(function($){
ls.blog.init();
/**
* Photoset
*/
ls.photoset.init();
/**
* Избраноое
*/

View file

@ -2,12 +2,12 @@
* Кнопка
*}
<button type="{if $sFieldType}{$sFieldType}{else}submit{/if}"
id="{$sFieldName}"
name="{$sFieldName}"
value="{if isset($sFieldValue)}{$sFieldValue}{else}{if isset($_aRequest[$sFieldName])}{$_aRequest[$sFieldName]}{/if}{/if}"
class="button {if $sFieldStyle}button-{$sFieldStyle}{/if} {$sFieldClasses}"
{if $bFieldIsDisabled}disabled{/if}>
{if $sFieldIcon}<i class="{$sFieldIcon}"></i>{/if}
<button type="{if $sFieldType}{$sFieldType}{else}submit{/if}"
id="{if $sFieldId}{$sFieldId}{else}{$sFieldName}{/if}"
name="{$sFieldName}"
value="{if isset($sFieldValue)}{$sFieldValue}{elseif isset($_aRequest[$sFieldName])}{$_aRequest[$sFieldName]}{/if}"
class="button {if $sFieldStyle}button-{$sFieldStyle}{/if} {$sFieldClasses}"
{if $bFieldIsDisabled}disabled{/if}>
{if $sFieldIcon}<i class="{$sFieldIcon}"></i>{/if}
{$sFieldText}
</button>

View file

@ -5,4 +5,4 @@
<input type="hidden"
id="{$sFieldName}"
name="{$sFieldName}"
value="{if $sFieldValue}{$sFieldValue}{else}{if $_aRequest[$sFieldName]}{$_aRequest[$sFieldName]}{/if}{/if}" />
value="{if $sFieldValue}{$sFieldValue|escape:'html'}{else}{if $_aRequest[$sFieldName]}{$_aRequest[$sFieldName]}{/if}{/if}" />

View file

@ -8,7 +8,7 @@
<input type="{if $sFieldType}{$sFieldType}{else}text{/if}"
id="{$sFieldName}"
name="{$sFieldName}"
value="{if isset($sFieldValue)}{$sFieldValue}{else}{if isset($_aRequest[$sFieldName])}{$_aRequest[$sFieldName]}{/if}{/if}"
value="{if isset($sFieldValue)}{$sFieldValue|escape:'html'}{else}{if isset($_aRequest[$sFieldName])}{$_aRequest[$sFieldName]}{/if}{/if}"
class="{if $sFieldClasses}{$sFieldClasses}{else}width-full{/if} js-input-{$sFieldName}"
{if $sFieldPlaceholder}placeholder="{$sFieldPlaceholder}"{/if}
{foreach $aFieldRules as $sRule}data-{$sRule} {/foreach}

View file

@ -7,5 +7,5 @@
rows="{$iFieldRows}"
{if $sFieldPlaceholder}placeholder="{$sFieldPlaceholder}"{/if}
{if $bFieldIsDisabled}disabled{/if}
{foreach $aFieldRules as $sRule}data-{$sRule} {/foreach}>{if $sFieldValue}{$sFieldValue}{else}{if $_aRequest[$sFieldName]}{$_aRequest[$sFieldName]}{/if}{/if}</textarea>
{foreach $aFieldRules as $sRule}data-{$sRule} {/foreach}>{if $sFieldValue}{$sFieldValue|escape:'html'}{else}{if $_aRequest[$sFieldName]}{$_aRequest[$sFieldName]}{/if}{/if}</textarea>
{/block}

View file

@ -24,14 +24,18 @@
{block name='add_topic_options'}{/block}
{* Подключение редактора *}
{include file='forms/editor.init.tpl' sMediaTargetType='topic'}
{$sMediaTargetId=''}
{if $oTopicEdit}
{$sMediaTargetId=$oTopicEdit->getId()}
{/if}
{include file='forms/editor.init.tpl' sMediaTargetType='topic' sMediaTargetId=$sMediaTargetId}
{hook run="add_topic_begin"}
{block name='add_topic_header_after'}{/block}
<form action="" method="POST" enctype="multipart/form-data" id="form-topic-add" class="js-form-validate" onsubmit="return ls.content.add('form-topic-add');">
<form action="" method="POST" enctype="multipart/form-data" id="form-topic-add" class="js-form-validate" onsubmit="return false;">
{hook run="form_add_topic_begin"}
{block name='add_topic_form_begin'}{/block}
@ -49,22 +53,23 @@
]}
{/foreach}
{include file='forms/form.field.select.tpl'
sFieldName = 'topic[blog_id]'
sFieldLabel = $aLang.topic_create_blog
sFieldNote = $aLang.topic_create_blog_notice
sFieldClasses = 'width-full js-topic-add-title'
aFieldItems = $aBlogs
sFieldSelectedValue = $_aRequest.blog_id}
{include file='forms/fields/form.field.select.tpl'
sFieldName = 'topic[blog_id]'
sFieldLabel = $aLang.topic_create_blog
sFieldNote = $aLang.topic_create_blog_notice
sFieldClasses = 'width-full js-topic-add-title'
aFieldItems = $aBlogs
sFieldSelectedValue = {($oTopicEdit) ? $oTopicEdit->getBlogId() : '' }}
{* Заголовок топика *}
{include file='forms/form.field.text.tpl'
sFieldName = 'topic[topic_title]'
sFieldEntityField = 'topic_title'
sFieldEntity = 'ModuleTopic_EntityTopic'
sFieldNote = $aLang.topic_create_title_notice
sFieldLabel = $aLang.topic_create_title}
{include file='forms/fields/form.field.text.tpl'
sFieldName = 'topic[topic_title]'
sFieldValue = {($oTopicEdit) ? $oTopicEdit->getTitle() : '' }
sFieldEntityField = 'topic_title'
sFieldEntity = 'ModuleTopic_EntityTopic'
sFieldNote = $aLang.topic_create_title_notice
sFieldLabel = $aLang.topic_create_title}
{block name='add_topic_form_text_before'}{/block}
@ -72,11 +77,12 @@
{* Текст топика *}
{* TODO: Max length for poll and link *}
{include file='forms/form.field.textarea.tpl'
sFieldName = 'topic[topic_text_source]'
sFieldRules = 'required="true" rangelength="[2,'|cat:$oConfig->Get('module.topic.max_length')|cat:']"'
sFieldLabel = $aLang.topic_create_text
sFieldClasses = 'width-full js-editor'}
{include file='forms/fields/form.field.textarea.tpl'
sFieldName = 'topic[topic_text_source]'
sFieldValue = {($oTopicEdit) ? $oTopicEdit->getTextSource() : '' }
sFieldRules = 'required="true" rangelength="[2,'|cat:$oConfig->Get('module.topic.max_length')|cat:']"'
sFieldLabel = $aLang.topic_create_text
sFieldClasses = 'width-full js-editor'}
{* Если визуальный редактор отключен выводим справку по разметке для обычного редактора *}
{if ! $oConfig->GetValue('view.wysiwyg')}
@ -88,27 +94,39 @@
{* Теги *}
{include file='forms/form.field.text.tpl'
sFieldName = 'topic[topic_tags]'
sFieldRules = 'required="true" rangetags="[1,15]"'
sFieldNote = $aLang.topic_create_tags_notice
sFieldLabel = $aLang.topic_create_tags
sFieldClasses = 'width-full autocomplete-tags-sep'}
{include file='forms/fields/form.field.text.tpl'
sFieldName = 'topic[topic_tags]'
sFieldValue = {($oTopicEdit) ? $oTopicEdit->getTags() : '' }
sFieldRules = 'required="true" rangetags="[1,15]"'
sFieldNote = $aLang.topic_create_tags_notice
sFieldLabel = $aLang.topic_create_tags
sFieldClasses = 'width-full autocomplete-tags-sep'}
{* Показывает дополнительные поля *}
{$aBlockParams = []}
{$aBlockParams.plugin = 'admin'}
{$aBlockParams.target_type = 'topic_'|cat:$sTopicType}
{if $oTopicEdit}
{$aBlockParams.target_id = $oTopicEdit->getId()}
{/if}
{insert name="block" block="propertyUpdate" params=$aBlockParams}
{* Запретить комментарии *}
{include file='forms/form.field.checkbox.tpl'
sFieldName = 'topic[topic_forbid_comment]'
sFieldNote = $aLang.topic_create_forbid_comment_notice
sFieldLabel = $aLang.topic_create_forbid_comment}
{include file='forms/fields/form.field.checkbox.tpl'
sFieldName = 'topic[topic_forbid_comment]'
bFieldChecked = {($oTopicEdit && $oTopicEdit->getForbidComment()) ? true : false }
sFieldNote = $aLang.topic_create_forbid_comment_notice
sFieldLabel = $aLang.topic_create_forbid_comment}
{* Принудительный вывод топиков на главную (доступно только админам) *}
{if $oUserCurrent->isAdministrator()}
{include file='forms/form.field.checkbox.tpl'
sFieldName = 'topic[topic_publish_index]'
sFieldNote = $aLang.topic_create_publish_index_notice
sFieldLabel = $aLang.topic_create_publish_index}
{include file='forms/fields/form.field.checkbox.tpl'
sFieldName = 'topic[topic_publish_index]'
bFieldChecked = {($oTopicEdit && $oTopicEdit->getPublishIndex()) ? true : false }
sFieldNote = $aLang.topic_create_publish_index_notice
sFieldLabel = $aLang.topic_create_publish_index}
{/if}
@ -116,6 +134,10 @@
{hook run="form_add_topic_end"}
{* Скрытые поля *}
{include file='forms/fields/form.field.hidden.tpl' sFieldName='topic_type' sFieldValue=$sTopicType}
{* Кнопки *}
{if $sEvent == 'add' or ($oTopicEdit and $oTopicEdit->getPublish() == 0)}
{$sSubmitInputText = $aLang.topic_create_submit_publish}
@ -123,18 +145,22 @@
{$sSubmitInputText = $aLang.topic_create_submit_update}
{/if}
{include file='forms/form.field.button.tpl'
sFieldName = 'submit_topic_publish'
sFieldStyle = 'primary'
sFieldClasses = 'fl-r'
sFieldText = $sSubmitInputText}
{include file='forms/form.field.button.tpl' sFieldType='button' sFieldClasses='js-topic-preview-text-button' sFieldText=$aLang.topic_create_submit_preview}
{include file='forms/form.field.button.tpl' sFieldName='submit_topic_save' sFieldText=$aLang.topic_create_submit_save}
</form>
{if $oTopicEdit}
{include file="forms/fields/form.field.hidden.tpl" sFieldName='topic[id]' sFieldValue=$oTopicEdit->getId()}
{/if}
{include file='forms/fields/form.field.button.tpl'
sFieldId = {($oTopicEdit) ? 'submit-edit-topic-publish' : 'submit-add-topic-publish' }
sFieldStyle = 'primary'
sFieldClasses = 'fl-r'
sFieldText = $sSubmitInputText}
{include file='forms/fields/form.field.button.tpl' sFieldType='button' sFieldClasses='js-topic-preview-text-button' sFieldText=$aLang.topic_create_submit_preview}
{include file='forms/fields/form.field.button.tpl' sFieldId={($oTopicEdit) ? 'submit-edit-topic-save' : 'submit-add-topic-save' } sFieldText=$aLang.topic_create_submit_save}
</form>
{* Блок с превью текста *}
<div class="topic-preview" style="display: none;" id="topic-text-preview"></div>
{* Блок с превью текста *}
<div class="topic-preview" style="display: none;" id="topic-text-preview"></div>
{block name='add_topic_end'}{/block}

View file

@ -21,10 +21,13 @@
{/function}
<ul class="write-list clearfix">
{modal_create_item sName='topic' sTitle=$aLang.block_create_topic_topic}
{$aTopicTypes=$LS->Topic_GetTopicTypes()}
{foreach $aTopicTypes as $oTopicType}
{modal_create_item sName='topic' url=$oTopicType->getUrlForAdd() sTitle=$oTopicType->getName()}
{/foreach}
{modal_create_item sName='blog' sTitle=$aLang.block_create_blog}
{modal_create_item sName='talk' sTitle=$aLang.block_create_talk}
{modal_create_item sName='draft' url="{router page='topic'}drafts/" sTitle="{$aLang.topic_menu_drafts} {if $iUserCurrentCountTopicDraft}({$iUserCurrentCountTopicDraft}){/if}"}
{modal_create_item sName='draft' url="{router page='content'}drafts/" sTitle="{$aLang.topic_menu_drafts} {if $iUserCurrentCountTopicDraft}({$iUserCurrentCountTopicDraft}){/if}"}
{hook run='write_item' isPopup=true}
</ul>

View file

@ -4,15 +4,15 @@
{if $sMenuItemSelect == 'topic'}
<ul class="nav nav-pills mb-30">
<li {if $sMenuSubItemSelect=='topic'}class="active"{/if}><a href="{router page='topic'}add/">{$aLang.topic_menu_add_topic}</a></li>
<li {if $sMenuSubItemSelect=='question'}class="active"{/if}><a href="{router page='question'}add/">{$aLang.topic_menu_add_question}</a></li>
<li {if $sMenuSubItemSelect=='link'}class="active"{/if}><a href="{router page='link'}add/">{$aLang.topic_menu_add_link}</a></li>
<li {if $sMenuSubItemSelect=='photoset'}class="active"{/if}><a href="{router page='photoset'}add/">{$aLang.topic_menu_add_photoset}</a></li>
{$aTopicTypes=$LS->Topic_GetTopicTypes()}
{foreach $aTopicTypes as $oTopicType}
<li {if $sMenuSubItemSelect==$oTopicType->getCode()}class="active"{/if}><a href="{$oTopicType->getUrlForAdd()}">{$oTopicType->getName()}</a></li>
{/foreach}
{hook run='menu_create_topic_item'}
{if $iUserCurrentCountTopicDraft}
<li class="{if $sMenuSubItemSelect == 'drafts'}active{/if}"><a href="{router page='topic'}drafts/">{$aLang.topic_menu_drafts} ({$iUserCurrentCountTopicDraft})</a></li>
<li class="{if $sMenuSubItemSelect == 'drafts'}active{/if}"><a href="{router page='content'}drafts/">{$aLang.topic_menu_drafts} ({$iUserCurrentCountTopicDraft})</a></li>
{/if}
</ul>
{/if}

View file

@ -41,7 +41,6 @@ $config['head']['default']['css'] = array_merge(Config::Get('head.default.css'),
"___path.skin.assets.web___/css/navs.css",
"___path.skin.assets.web___/css/tables.css",
"___path.skin.assets.web___/css/topic.css",
"___path.skin.assets.web___/css/photoset.css",
"___path.skin.assets.web___/css/comments.css",
"___path.skin.assets.web___/css/blocks.css",
"___path.skin.assets.web___/css/blog.css",

View file

@ -1,16 +0,0 @@
{**
* Топик ссылка
*
* @styles css/topic.css
*}
{extends file='topics/topic_base.tpl'}
{block name='topic_icon'}<i class="icon-share-alt" title="{$aLang.topic_link}"></i>{/block}
{block name='topic_content_after'}
<div class="topic-url">
<a href="{router page='link'}go/{$oTopic->getId()}/" title="{$aLang.topic_link_count_jump}: {$oTopic->getLinkCountJump()}">{$oTopic->getLinkUrl()}</a>
</div>
{/block}

View file

@ -1,86 +0,0 @@
{**
* Топик фотосет
*
* @styles css/topic.css
*}
{extends file='topics/topic_base.tpl'}
{* Preview Image *}
{block name='topic_header_after'}
{$oMainPhoto = $oTopic->getPhotosetMainPhoto()}
{if $oMainPhoto}
<div class="topic-preview-image">
<div class="topic-preview-image-inner js-topic-preview-loader loading" onclick="window.location='{$oTopic->getUrl()}'">
<div class="topic-preview-image-count" id="photoset-photo-count-{$oTopic->getId()}"><i class="icon-camera icon-white"></i> {$oTopic->getPhotosetCount()}</div>
{if $oMainPhoto->getDescription()}
<div class="topic-preview-image-desc" id="photoset-photo-desc-{$oTopic->getId()}">{$oMainPhoto->getDescription()}</div>
{/if}
<img class="js-topic-preview-image" src="{$oMainPhoto->getWebPath(1000)}" alt="Topic preview" />
</div>
</div>
{/if}
{/block}
{* Текст *}
{block name='topic_content_text'}
{if $bTopicList}
{$oTopic->getTextShort()}
{if $oTopic->getTextShort() != $oTopic->getText()}
{$iPhotosCount = $oTopic->getPhotosetCount()}
<br />
<a href="{$oTopic->getUrl()}#cut" title="{$aLang.topic_read_more}">
{if $oTopic->getCutText()}
{$oTopic->getCutText()}
{else}
{$aLang.topic_photoset_show_all|ls_lang:"COUNT%%`$iPhotosCount`"} &rarr;
{/if}
</a>
{/if}
{else}
{$oTopic->getText()}
{/if}
{/block}
{* Photoset *}
{block name='topic_content_after'}
{if ! $bTopicList}
<div class="photoset photoset-type-default">
<h2 class="photoset-title">{$oTopic->getPhotosetCount()} {$oTopic->getPhotosetCount()|declension:$aLang.topic_photoset_count_images}</h2>
<ul class="photoset-images" id="topic-photo-images">
{$aPhotos = $oTopic->getPhotosetPhotos(0, $oConfig->get('module.topic.photoset.per_page'))}
{if $aPhotos}
{foreach $aPhotos as $oPhoto}
<li>
<a class="js-photoset-type-default-image"
href="{$oPhoto->getWebPath(1000)}"
rel="[photoset]" title="{$oPhoto->getDescription()}">
<img src="{$oPhoto->getWebPath('50crop')}" alt="{$oPhoto->getDescription()}" /></a>
</li>
{$iLastPhotoId = $oPhoto->getId()}
{/foreach}
{/if}
<script type="text/javascript">
ls.photoset.idLast='{$iLastPhotoId}';
</script>
</ul>
{if count($aPhotos) < $oTopic->getPhotosetCount()}
<a href="javascript:ls.photoset.getMore({$oTopic->getId()})" id="topic-photo-more" class="get-more">{$aLang.topic_photoset_show_more} &darr;</a>
{/if}
</div>
{/if}
{/block}

View file

@ -1,25 +0,0 @@
{**
* Топик опрос
*
* @styles css/topic.css
* @scripts <framework>/js/livestreet/poll.js
*}
{extends file='topics/topic_base.tpl'}
{block name='topic_header_after'}
<div class="poll js-poll" data-poll-id="{$oTopic->getId()}">
{if ! $oTopic->getUserQuestionIsVote()}
<ul class="poll-list js-poll-list">
{foreach $oTopic->getQuestionAnswers() as $iItemId => $aAnswer}
<li class="poll-item js-poll-item"><label><input type="radio" name="poll-{$oTopic->getId()}" value="{$iItemId}" class="js-poll-item-option" /> {$aAnswer.text|escape}</label></li>
{/foreach}
</ul>
<button type="submit" class="button button-primary js-poll-button-vote">{$aLang.topic_question_vote}</button>
<button type="submit" class="button js-poll-button-abstain">{$aLang.topic_question_abstain}</button>
{else}
{include file='topics/poll_result.tpl'}
{/if}
</div>
{/block}

View file

@ -1,23 +0,0 @@
{**
* Обычный топик
*
* @styles css/topic.css
*}
{extends file='topics/topic_base.tpl'}
{block name='topic_content_text'}
{if $bTopicList}
{$oTopic->getTextShort()}
{if $oTopic->getTextShort() != $oTopic->getText()}
<br/>
<a href="{$oTopic->getUrl()}#cut" title="{$aLang.topic_read_more}">
{$oTopic->getCutText()|default:$aLang.topic_read_more}
</a>
{/if}
{else}
{$oTopic->getText()}
{/if}
{/block}

View file

@ -3,5 +3,12 @@
*}
{if $LS->Topic_IsAllowTopicType($oTopic->getType())}
{include file="topics/topic.{$oTopic->getType()}.tpl"}
{if $LS->Topic_IsAllowTopicType($oTopic->getType())}
{$sTemplateType="topics/topic.type.{$oTopic->getType()}.tpl"}
{if $LS->Viewer_TemplateExists($sTemplateType)}
{include file=$sTemplateType}
{else}
{include file="topics/topic_base.tpl"}
{/if}
{/if}
{/if}

View file

@ -55,7 +55,7 @@
{if $oTopic->getIsAllowDelete()}
<li>
<i class="icon-trash"></i>
<a href="{router page='topic'}delete/{$oTopic->getId()}/?security_ls_key={$LIVESTREET_SECURITY_KEY}"
<a href="{$oTopic->getUrlDelete()}?security_ls_key={$LIVESTREET_SECURITY_KEY}"
title="{$aLang.topic_delete}"
onclick="return confirm('{$aLang.topic_delete_confirm}');"
class="actions-delete">{$aLang.topic_delete}</a>
@ -76,7 +76,28 @@
<div class="topic-content text">
{hook run='topic_content_begin' topic=$oTopic bTopicList=$bTopicList}
{block name='topic_content_text'}{$oTopic->getText()}{/block}
{block name='topic_content_text'}
{if $bTopicList}
{$oTopic->getTextShort()}
{if $oTopic->getTextShort() != $oTopic->getText()}
<br/>
<a href="{$oTopic->getUrl()}#cut" title="{$aLang.topic_read_more}">
{$oTopic->getCutText()|default:$aLang.topic_read_more}
</a>
{/if}
{else}
{$oTopic->getText()}
{/if}
{/block}
{$aProperties = $oTopic->getPropertyList()}
{foreach $aProperties as $oProperty}
<br/>
{$mValue = $oProperty->getValue()->getValueForDisplay()}
<b>{$oProperty->getTitle()}</b>: {$mValue}
{/foreach}
{hook run='topic_content_end' topic=$oTopic bTopicList=$bTopicList}
</div>

View file

@ -7,7 +7,12 @@
{foreach $aTopics as $oTopic}
{if $LS->Topic_IsAllowTopicType($oTopic->getType())}
{include file="topics/topic.{$oTopic->getType()}.tpl" bTopicList=true}
{$sTemplateType="topics/topic.type.{$oTopic->getType()}.tpl"}
{if $LS->Viewer_TemplateExists($sTemplateType)}
{include file=$sTemplateType bTopicList=true}
{else}
{include file="topics/topic_base.tpl" bTopicList=true}
{/if}
{/if}
{/foreach}

View file

@ -59,7 +59,7 @@
</footer>
</article>
{* TODO: Пофиксить кнопки сабмита *}
<button type="submit" name="submit_topic_publish" class="button button-primary fl-r" onclick="jQuery('#submit_topic_publish').trigger('click');">
{if $sEvent == 'add' or ($oTopicEdit and $oTopicEdit->getPublish() == 0)}
{$aLang.topic_create_submit_publish}

@ -1 +1 @@
Subproject commit 143860c7eba5a047551a92203d1a12e270c81c27
Subproject commit 021c2cc845771527931a191495ed8418891c1277

View file

@ -193,3 +193,28 @@ CREATE TABLE IF NOT EXISTS `prefix_media_target` (
--
ALTER TABLE `prefix_media_target`
ADD CONSTRAINT `prefix_media_target_ibfk_1` FOREIGN KEY (`media_id`) REFERENCES `prefix_media` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- 10-01-2014
ALTER TABLE `prefix_topic` CHANGE `topic_type` `topic_type` VARCHAR( 50 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'topic';
-- 11-01-2014
CREATE TABLE IF NOT EXISTS `prefix_topic_type` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(250) NOT NULL,
`name_many` varchar(250) NOT NULL,
`code` varchar(50) NOT NULL,
`allow_remove` tinyint(1) NOT NULL DEFAULT '0',
`date_create` datetime NOT NULL,
`state` tinyint(4) NOT NULL DEFAULT '1',
`params` text,
PRIMARY KEY (`id`),
KEY `code` (`code`),
KEY `state` (`state`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Дамп данных таблицы `prefix_topic_type`
--
INSERT INTO `prefix_topic_type` (`id`, `name`, `name_many`, `code`, `allow_remove`, `date_create`, `state`, `params`) VALUES
(1, 'Топик', 'Топики', 'topic', 0, '2014-01-11 00:00:00', 1, NULL);

View file

@ -12,8 +12,5 @@ Disallow: /tag/$
Disallow: /page/$
Disallow: /error/$
Disallow: /settings/$
Disallow: /photoset/$
Disallow: /topic/$
Disallow: /link/$
Disallow: /question/$
Disallow: /content/$
Disallow: /talk/$