/** * Обработка добавление комментария к топику * */ protected function SubmitComment() { // * Проверям авторизован ли пользователь if (!E::ModuleUser()->IsAuthorization()) { E::ModuleMessage()->AddErrorSingle(E::ModuleLang()->Get('need_authorization'), E::ModuleLang()->Get('error')); return; } // * Проверяем топик if (!($oTopic = E::ModuleTopic()->GetTopicById(F::GetRequestStr('cmt_target_id')))) { E::ModuleMessage()->AddErrorSingle(E::ModuleLang()->Get('system_error'), E::ModuleLang()->Get('error')); return; } // * Возможность постить коммент в топик в черновиках if (!$oTopic->getPublish()) { E::ModuleMessage()->AddErrorSingle(E::ModuleLang()->Get('system_error'), E::ModuleLang()->Get('error')); return; } // * Проверяем разрешено ли постить комменты switch (E::ModuleACL()->CanPostComment($this->oUserCurrent, $oTopic)) { case ModuleACL::CAN_TOPIC_COMMENT_ERROR_BAN: E::ModuleMessage()->AddErrorSingle(E::ModuleLang()->Get('topic_comment_banned'), E::ModuleLang()->Get('attention')); return; case ModuleACL::CAN_TOPIC_COMMENT_FALSE: E::ModuleMessage()->AddErrorSingle(E::ModuleLang()->Get('topic_comment_acl'), E::ModuleLang()->Get('error')); return; } // * Проверяем разрешено ли постить комменты по времени if (!E::ModuleACL()->CanPostCommentTime($this->oUserCurrent)) { E::ModuleMessage()->AddErrorSingle(E::ModuleLang()->Get('topic_comment_limit'), E::ModuleLang()->Get('error')); return; } // * Проверяем запрет на добавления коммента автором топика if ($oTopic->getForbidComment()) { E::ModuleMessage()->AddErrorSingle(E::ModuleLang()->Get('topic_comment_notallow'), E::ModuleLang()->Get('error')); return; } // * Проверяем текст комментария $sText = E::ModuleText()->Parse(F::GetRequestStr('comment_text')); if (!F::CheckVal($sText, 'text', Config::Val('module.comment.min_length', 2), Config::Val('module.comment.max_length', 10000))) { E::ModuleMessage()->AddErrorSingle(E::ModuleLang()->Get('topic_comment_text_len', array('min' => 2, 'max' => Config::Val('module.comment.max_length', 10000))), E::ModuleLang()->Get('error')); return; } $iMin = Config::Val('module.comment.min_length', 2); $iMax = Config::Val('module.comment.max_length', 0); if (!F::CheckVal($sText, 'text', $iMin, $iMax)) { if ($iMax) { E::ModuleMessage()->AddErrorSingle(E::ModuleLang()->Get('topic_comment_text_len', array('min' => $iMin, 'max' => $iMax)), E::ModuleLang()->Get('error')); } else { E::ModuleMessage()->AddErrorSingle(E::ModuleLang()->Get('topic_comment_text_min', array('min' => $iMin)), E::ModuleLang()->Get('error')); } return; } // * Проверям на какой коммент отвечаем if (!$this->isPost('reply')) { E::ModuleMessage()->AddErrorSingle(E::ModuleLang()->Get('system_error'), E::ModuleLang()->Get('error')); return; } $oCommentParent = null; $iParentId = intval(F::GetRequest('reply')); if ($iParentId != 0) { // * Проверяем существует ли комментарий на который отвечаем if (!($oCommentParent = E::ModuleComment()->GetCommentById($iParentId))) { E::ModuleMessage()->AddErrorSingle(E::ModuleLang()->Get('system_error'), E::ModuleLang()->Get('error')); return; } // * Проверяем из одного топика ли новый коммент и тот на который отвечаем if ($oCommentParent->getTargetId() != $oTopic->getId()) { E::ModuleMessage()->AddErrorSingle(E::ModuleLang()->Get('system_error'), E::ModuleLang()->Get('error')); return; } } else { // * Корневой комментарий $iParentId = null; } // * Проверка на дублирующий коммент if (E::ModuleComment()->GetCommentUnique($oTopic->getId(), 'topic', $this->oUserCurrent->getId(), $iParentId, md5($sText))) { E::ModuleMessage()->AddErrorSingle(E::ModuleLang()->Get('topic_comment_spam'), E::ModuleLang()->Get('error')); return; } // * Создаём коммент /** @var ModuleComment_EntityComment $oCommentNew */ $oCommentNew = E::GetEntity('Comment'); $oCommentNew->setTargetId($oTopic->getId()); $oCommentNew->setTargetType('topic'); $oCommentNew->setTargetParentId($oTopic->getBlog()->getId()); $oCommentNew->setUserId($this->oUserCurrent->getId()); $oCommentNew->setText($sText); $oCommentNew->setDate(F::Now()); $oCommentNew->setUserIp(F::GetUserIp()); $oCommentNew->setPid($iParentId); $oCommentNew->setTextHash(md5($sText)); $oCommentNew->setPublish($oTopic->getPublish()); // * Добавляем коммент E::ModuleHook()->Run('comment_add_before', array('oCommentNew' => $oCommentNew, 'oCommentParent' => $oCommentParent, 'oTopic' => $oTopic)); if (E::ModuleComment()->AddComment($oCommentNew)) { E::ModuleHook()->Run('comment_add_after', array('oCommentNew' => $oCommentNew, 'oCommentParent' => $oCommentParent, 'oTopic' => $oTopic)); E::ModuleViewer()->AssignAjax('sCommentId', $oCommentNew->getId()); if ($oTopic->getPublish()) { // * Добавляем коммент в прямой эфир если топик не в черновиках /** @var ModuleComment_EntityCommentOnline $oCommentOnline */ $oCommentOnline = E::GetEntity('Comment_CommentOnline'); $oCommentOnline->setTargetId($oCommentNew->getTargetId()); $oCommentOnline->setTargetType($oCommentNew->getTargetType()); $oCommentOnline->setTargetParentId($oCommentNew->getTargetParentId()); $oCommentOnline->setCommentId($oCommentNew->getId()); E::ModuleComment()->AddCommentOnline($oCommentOnline); } // * Список емайлов на которые не нужно отправлять уведомление $aExcludeMail = array($this->oUserCurrent->getMail()); // * Отправляем уведомление тому на чей коммент ответили if ($oCommentParent && $oCommentParent->getUserId() != $oTopic->getUserId() && $oCommentNew->getUserId() != $oCommentParent->getUserId()) { $oUserAuthorComment = $oCommentParent->getUser(); $aExcludeMail[] = $oUserAuthorComment->getMail(); E::ModuleNotify()->SendCommentReplyToAuthorParentComment($oUserAuthorComment, $oTopic, $oCommentNew, $this->oUserCurrent); } // issue 131 (https://github.com/altocms/altocms/issues/131) // Не работает настройка уведомлений о комментариях к своим топикам // Уберём автора топика из рассылки /** @var ModuleTopic_EntityTopic $oTopic */ $aExcludeMail[] = $oTopic->getUser()->getMail(); // Отправим ему сообщение через отдельный метод, который проверяет эту настройку /** @var ModuleComment_EntityComment $oCommentNew */ E::ModuleNotify()->SendCommentNewToAuthorTopic($oTopic->getUser(), $oTopic, $oCommentNew, $this->oUserCurrent); // * Отправка уведомления всем, кто подписан на топик кроме автора E::ModuleSubscribe()->Send('topic_new_comment', $oTopic->getId(), 'comment_new.tpl', E::ModuleLang()->Get('notify_subject_comment_new'), array('oTopic' => $oTopic, 'oComment' => $oCommentNew, 'oUserComment' => $this->oUserCurrent), $aExcludeMail); // * Подписываем автора коммента на обновления в трекере $oTrack = E::ModuleSubscribe()->AddTrackSimple('topic_new_comment', $oTopic->getId(), $this->oUserCurrent->getId()); if ($oTrack) { //если пользователь не отписался от обновлений топика if (!$oTrack->getStatus()) { $oTrack->setStatus(1); E::ModuleSubscribe()->UpdateTrack($oTrack); } } // * Добавляем событие в ленту E::ModuleStream()->Write($oCommentNew->getUserId(), 'add_comment', $oCommentNew->getId(), $oTopic->getPublish() && !$oTopic->getBlog()->IsPrivate()); } else { E::ModuleMessage()->AddErrorSingle(E::ModuleLang()->Get('system_error'), E::ModuleLang()->Get('error')); } }
/** * Возвращает объект трекинга на новые комментарии к топику * * @return ModuleSubscribe_EntitySubscribe|null */ public function getTrackNewComment() { if (!($oUserCurrent = E::ModuleUser()->GetUserCurrent())) { return null; } return E::ModuleSubscribe()->GetTrackByTargetAndUser('topic_new_comment', $this->getId(), $oUserCurrent->getId()); }
/** * Обработка добавления топика * * @return bool|string */ protected function SubmitAdd() { // * Проверяем отправлена ли форма с данными (хотяб одна кнопка) if (!F::isPost('submit_topic_publish') && !F::isPost('submit_topic_draft') && !F::isPost('submit_topic_save')) { return false; } /** @var ModuleTopic_EntityTopic $oTopic */ $oTopic = E::GetEntity('Topic'); $oTopic->_setValidateScenario('topic'); // * Заполняем поля для валидации $oTopic->setBlogId(F::GetRequestStr('blog_id')); // issue 151 (https://github.com/altocms/altocms/issues/151) // Некорректная обработка названия блога // $oTopic->setTitle(strip_tags(F::GetRequestStr('topic_title'))); $oTopic->setTitle(E::ModuleTools()->RemoveAllTags(F::GetRequestStr('topic_title'))); $oTopic->setTextSource(F::GetRequestStr('topic_text')); $oTopic->setUserId($this->oUserCurrent->getId()); $oTopic->setType($this->oContentType->getContentUrl()); if ($this->oContentType->isAllow('link')) { $oTopic->setSourceLink(F::GetRequestStr('topic_field_link')); } $oTopic->setTags(F::GetRequestStr('topic_field_tags')); $oTopic->setDateAdd(F::Now()); $oTopic->setUserIp(F::GetUserIp()); $sTopicUrl = E::ModuleTopic()->CorrectTopicUrl($oTopic->MakeTopicUrl()); $oTopic->setTopicUrl($sTopicUrl); // * Проверка корректности полей формы if (!$this->checkTopicFields($oTopic)) { return false; } // * Определяем в какой блог делаем запись $nBlogId = $oTopic->getBlogId(); if ($nBlogId == 0) { $oBlog = E::ModuleBlog()->GetPersonalBlogByUserId($this->oUserCurrent->getId()); } else { $oBlog = E::ModuleBlog()->GetBlogById($nBlogId); } // * Если блог не определен, то выдаем предупреждение if (!$oBlog) { E::ModuleMessage()->AddErrorSingle(E::ModuleLang()->Get('topic_create_blog_error_unknown'), E::ModuleLang()->Get('error')); return false; } // * Проверяем права на постинг в блог if (!E::ModuleACL()->IsAllowBlog($oBlog, $this->oUserCurrent)) { E::ModuleMessage()->AddErrorSingle(E::ModuleLang()->Get('topic_create_blog_error_noallow'), E::ModuleLang()->Get('error')); return false; } // * Проверяем разрешено ли постить топик по времени if (F::isPost('submit_topic_publish') && !E::ModuleACL()->CanPostTopicTime($this->oUserCurrent)) { E::ModuleMessage()->AddErrorSingle(E::ModuleLang()->Get('topic_time_limit'), E::ModuleLang()->Get('error')); return false; } // * Теперь можно смело добавлять топик к блогу $oTopic->setBlogId($oBlog->getId()); // * Получаемый и устанавливаем разрезанный текст по тегу <cut> list($sTextShort, $sTextNew, $sTextCut) = E::ModuleText()->Cut($oTopic->getTextSource()); $oTopic->setCutText($sTextCut); $oTopic->setText(E::ModuleText()->Parser($sTextNew)); // Получаем ссылки, полученные при парсинге текста $oTopic->setTextLinks(E::ModuleText()->GetLinks()); $oTopic->setTextShort(E::ModuleText()->Parser($sTextShort)); // * Варианты ответов if ($this->oContentType->isAllow('poll') && F::GetRequestStr('topic_field_question') && F::GetRequest('topic_field_answers', array())) { $oTopic->setQuestionTitle(strip_tags(F::GetRequestStr('topic_field_question'))); $oTopic->clearQuestionAnswer(); $aAnswers = F::GetRequest('topic_field_answers', array()); foreach ($aAnswers as $sAnswer) { $sAnswer = trim((string) $sAnswer); if ($sAnswer) { $oTopic->addQuestionAnswer($sAnswer); } } } $aPhotoSetData = E::ModuleMresource()->GetPhotosetData('photoset', 0); $oTopic->setPhotosetCount($aPhotoSetData['count']); if ($aPhotoSetData['cover']) { $oTopic->setPhotosetMainPhotoId($aPhotoSetData['cover']); } // * Публикуем или сохраняем if (isset($_REQUEST['submit_topic_publish'])) { $oTopic->setPublish(1); $oTopic->setPublishDraft(1); $oTopic->setDateShow(F::Now()); } else { $oTopic->setPublish(0); $oTopic->setPublishDraft(0); } // * Принудительный вывод на главную $oTopic->setPublishIndex(0); if (E::ModuleACL()->IsAllowPublishIndex($this->oUserCurrent)) { if (F::GetRequest('topic_publish_index')) { $oTopic->setPublishIndex(1); } } // * Запрет на комментарии к топику $oTopic->setForbidComment(F::GetRequest('topic_forbid_comment', 0)); // Разрешение/запрет индексации контента топика изначально - как у блога if ($oBlogType = $oBlog->GetBlogType()) { // Если тип блога определен, то берем из типа блога... $oTopic->setTopicIndexIgnore($oBlogType->GetIndexIgnore()); } else { // ...если нет, то индексацию разрешаем $oTopic->setTopicIndexIgnore(false); } $oTopic->setShowPhotoset(F::GetRequest('topic_show_photoset', 0)); // * Запускаем выполнение хуков E::ModuleHook()->Run('topic_add_before', array('oTopic' => $oTopic, 'oBlog' => $oBlog)); // * Добавляем топик if ($this->_addTopic($oTopic)) { E::ModuleHook()->Run('topic_add_after', array('oTopic' => $oTopic, 'oBlog' => $oBlog)); // * Получаем топик, чтоб подцепить связанные данные $oTopic = E::ModuleTopic()->GetTopicById($oTopic->getId()); // * Обновляем количество топиков в блоге E::ModuleBlog()->RecalculateCountTopicByBlogId($oTopic->getBlogId()); // * Добавляем автора топика в подписчики на новые комментарии к этому топику E::ModuleSubscribe()->AddSubscribeSimple('topic_new_comment', $oTopic->getId(), $this->oUserCurrent->getMail(), $this->oUserCurrent->getId()); // * Подписываем автора топика на обновления в трекере if ($oTrack = E::ModuleSubscribe()->AddTrackSimple('topic_new_comment', $oTopic->getId(), $this->oUserCurrent->getId())) { // Если пользователь не отписался от обновлений топика if (!$oTrack->getStatus()) { $oTrack->setStatus(1); E::ModuleSubscribe()->UpdateTrack($oTrack); } } // * Делаем рассылку всем, кто состоит в этом блоге if ($oTopic->getPublish() == 1 && $oBlog->getType() != 'personal') { E::ModuleTopic()->SendNotifyTopicNew($oBlog, $oTopic, $this->oUserCurrent); } /** * Привязываем фото к ID топика */ if (isset($aPhotos) && count($aPhotos)) { E::ModuleTopic()->AttachTmpPhotoToTopic($oTopic); } // * Удаляем временную куку E::ModuleSession()->DelCookie('ls_photoset_target_tmp'); // Обработаем фотосет if ($this->oContentType->isAllow('photoset') && ($sTargetTmp = E::ModuleSession()->GetCookie(ModuleUploader::COOKIE_TARGET_TMP))) { // Уберем у ресурса флаг временного размещения и удалим из куки target_tmp E::ModuleSession()->DelCookie(ModuleUploader::COOKIE_TARGET_TMP); } // * Добавляем событие в ленту E::ModuleStream()->Write($oTopic->getUserId(), 'add_topic', $oTopic->getId(), $oTopic->getPublish() && (!$oBlog->getBlogType() || !$oBlog->getBlogType()->IsPrivate())); R::Location($oTopic->getUrl()); } else { E::ModuleMessage()->AddErrorSingle(E::ModuleLang()->Get('system_error')); F::SysWarning('System Error'); return R::Action('error'); } }
/** * Изменение состояния подписки */ protected function EventAjaxTrackToggle() { /** * Устанавливаем формат Ajax ответа */ E::ModuleViewer()->SetResponseAjax('json'); if (!$this->oUserCurrent) { E::ModuleMessage()->AddError(E::ModuleLang()->Get('need_authorization'), E::ModuleLang()->Get('error')); return; } /** * Получаем тип объекта подписки */ $sTargetType = F::GetRequestStr('target_type'); if (!E::ModuleSubscribe()->IsAllowTargetType($sTargetType)) { E::ModuleMessage()->AddError(E::ModuleLang()->Get('system_error'), E::ModuleLang()->Get('error')); return; } $sTargetId = F::GetRequestStr('target_id') ? F::GetRequestStr('target_id') : null; $iValue = F::GetRequest('value') ? 1 : 0; $oTrack = null; /** * Проверка объекта подписки */ if (!E::ModuleSubscribe()->CheckTarget($sTargetType, $sTargetId, $iValue)) { E::ModuleMessage()->AddError(E::ModuleLang()->Get('system_error'), E::ModuleLang()->Get('error')); return; } /** * Если подписка еще не существовала, то создаем её */ if ($oTrack = E::ModuleSubscribe()->AddTrackSimple($sTargetType, $sTargetId, $this->oUserCurrent->getId())) { $oTrack->setStatus($iValue); E::ModuleSubscribe()->UpdateTrack($oTrack); E::ModuleMessage()->AddNotice(E::ModuleLang()->Get('subscribe_change_ok'), E::ModuleLang()->Get('attention')); return; } E::ModuleMessage()->AddError(E::ModuleLang()->Get('system_error'), E::ModuleLang()->Get('error')); return; }
/** * Получить ленту топиков по подписке * * @param int $iUserId ID пользователя, для которого получаем ленту * @param int $iPage * @param int $iPerPage * @param bool $iOnlyNew * * @return mixed */ public function Trackread($iUserId, $iPage = 1, $iPerPage = 10, $iOnlyNew = false) { $aTopicTracks = E::ModuleSubscribe()->GetTracks(array('user_id' => $iUserId, 'target_type' => 'topic_new_comment', 'status' => 1, 'only_new' => $iOnlyNew), array('date_add' => 'desc'), $iPage, $iPerPage); $aTopicsIds = array(); /** @var ModuleSubscribe_EntityTrack $oTrack */ foreach ($aTopicTracks['collection'] as $oTrack) { $aTopicsIds[] = $oTrack->getTargetId(); } $aTopicTracks['collection'] = E::ModuleTopic()->GetTopicsAdditionalData($aTopicsIds); return $aTopicTracks; }
/** * Производит отправку писем по подписчикам подписки * * @param int $sTargetType Тип объекта подписки * @param int $iTargetId ID объекта подписки * @param string $sTemplate Имя шаблона письма, например, mail.tpl * @param string $sTitle Заголовок письма * @param array $aParams Параметра для передачи в шаблон письма * @param array $aExcludeMail Список емайлов на которые НЕ нужно отправлять * @param string $sPluginName Название или класс плагина для корректной отправки */ public function Send($sTargetType, $iTargetId, $sTemplate, $sTitle, $aParams = array(), $aExcludeMail = array(), $sPluginName = null) { $iPage = 1; $aSubscribes = E::ModuleSubscribe()->GetSubscribes(array('target_type' => $sTargetType, 'target_id' => $iTargetId, 'status' => 1, 'exclude_mail' => $aExcludeMail), array(), $iPage, 20); while ($aSubscribes['collection']) { $iPage++; foreach ($aSubscribes['collection'] as $oSubscribe) { $aParams['sSubscribeKey'] = $oSubscribe->getKey(); E::ModuleNotify()->Send($oSubscribe->getMail(), $sTemplate, $sTitle, $aParams, $sPluginName); } $aSubscribes = E::ModuleSubscribe()->GetSubscribes(array('target_type' => $sTargetType, 'target_id' => $iTargetId, 'status' => 1, 'exclude_mail' => $aExcludeMail), array(), $iPage, 20); } }
/** * Обработка подтверждения нового емайла при смене старого */ public function EventChangemailConfirmTo() { if (!($oChangemail = E::ModuleUser()->GetUserChangemailByCodeTo($this->GetParamEventMatch(1, 0)))) { return parent::EventNotFound(); } if (!$oChangemail->getConfirmFrom() || $oChangemail->getConfirmTo() || strtotime($oChangemail->getDateExpired()) < time()) { return parent::EventNotFound(); } $oChangemail->setConfirmTo(1); $oChangemail->setDateUsed(F::Now()); E::ModuleUser()->UpdateUserChangemail($oChangemail); $oUser = E::ModuleUser()->GetUserById($oChangemail->getUserId()); $oUser->setMail($oChangemail->getMailTo()); E::ModuleUser()->Update($oUser); /** * Меняем емайл в подписках */ if ($oChangemail->getMailFrom()) { E::ModuleSubscribe()->ChangeSubscribeMail($oChangemail->getMailFrom(), $oChangemail->getMailTo(), $oUser->getId()); } E::ModuleViewer()->Assign('sText', E::ModuleLang()->Get('settings_profile_mail_change_ok', array('mail' => htmlspecialchars($oChangemail->getMailTo())))); // Исправление ошибки смены email {@link https://github.com/altocms/altocms/issues/260} E::ModuleViewer()->Assign('oUserProfile', $oUser); $this->SetTemplateAction('changemail_confirm'); }