protected function updateTopicFixedStatus(ModuleTopic_EntityTopic $oTopic) { $sql = 'UPDATE ' . Config::Get('db.table.topic') . ' SET topic_fixed = ? WHERE topic_id = ?d'; if ($this->oDb->query($sql, $oTopic->getFixedStatus(), $oTopic->getId()) !== null) { return true; } return false; }
/** * Возвращает похожие записи для объекта топика (по тегам) * * @param ModuleTopic_EntityTopic $oTopic * * @return array */ public function getSimilarTopicsForTopic(ModuleTopic_EntityTopic $oTopic) { if ($oTopic == null) { return array(); } // Вытаскиваем переменные с файлов Config // Максимальное количество топиков, которое выводится в блоке - iCountTopics // По какому параметру сортировать записи - sOrderBy // Как сортировать топики в выдаче $iCountTopics = Config::Get('plugin.similar.max_topics_count'); $sOrderBy = Config::Get('plugin.similar.topics_order_by'); $iOrderByDirection = Config::Get('plugin.similar.topics_order_by_direction'); $sLang = null; if (in_array('l10n', $this->Plugin_GetActivePlugins())) { $sLang = $this->PluginL10n_L10n_GetLangForQuery(); } // Генерируем ключ для кеша $key = "simular_topics_by_tags_for_" . $oTopic->getId() . ($sLang ? "_{$sLang}" : "") . "_{$iCountTopics}_{$sOrderBy}_{$iOrderByDirection}"; if (!($aTopicIds = $this->Cache_Get($key))) { $aTopicIds = $this->oMapper->getTopicIdForTags($oTopic->getTagsArray(), $iCountTopics + 1, $sOrderBy, $iOrderByDirection, $sLang); unset($aTopicIds[array_search($oTopic->getId(), $aTopicIds)]); // Кешируем массив топиков на один час $this->Cache_Set($aTopicIds, $key, array('topic_update'), 60 * 10); } // Пытаемся вытянуть массив топиков из кеша // Массив id'шек топиков похожих на текущий // Достаем топики вместе с дополнительной информацией (автор, блог и т.д.) $aTopics = $this->Topic_GetTopicsAdditionalData($aTopicIds, array('user' => array(), 'blog' => array('owner' => array()))); // Удаляем топики из недоступных для пользователя блогов $oUser = $this->User_GetUserCurrent(); $aInaccessibleBlogIds = $this->Blog_GetInaccessibleBlogsByUser($oUser); foreach ($aTopics as $oTopic) { if (in_array($oTopic->getBlogId(), $aInaccessibleBlogIds)) { unset($aTopics[$oTopic->getTopicId()]); } } return $aTopics; }
protected function updateTopicadditionalfields(ModuleTopic_EntityTopic $oTopic) { $sql = 'UPDATE ' . Config::Get('db.table.topic') . ' SET now_listening = ? , current_place = ? , mood = ? WHERE topic_id = ?d'; if ($this->oDb->query($sql, $oTopic->getNowListening(), $oTopic->getCurrentPlace(), $oTopic->getMood(), $oTopic->getId()) !== null) { return true; } return false; }
/** * @param ModuleTopic_EntityTopic $oTopic * @param null $sTargetTmp * @return bool */ public function AttachTmpPhotoToTopic($oTopic, $sTargetTmp = null) { if (is_null($sTargetTmp)) { $sTargetTmp = E::ModuleSession()->GetCookie(ModuleUploader::COOKIE_TARGET_TMP); } E::ModuleMresource()->ResetTmpRelById($sTargetTmp, $oTopic->getId()); return $this->oMapper->attachTmpPhotoToTopic($oTopic, $sTargetTmp); }
/** * Формирует и возвращает полный ЧПУ URL для топика * * @param ModuleTopic_EntityTopic $oTopic * @param bool $bAbsolute При false вернет относительный УРЛ * @return string */ public function BuildUrlForTopic($oTopic, $bAbsolute = true) { $sUrlMask = Config::Get('module.topic.url'); $iDateCreate = strtotime($oTopic->getDatePublish()); $aReplace = array('%year%' => date("Y", $iDateCreate), '%month%' => date("m", $iDateCreate), '%day%' => date("d", $iDateCreate), '%hour%' => date("H", $iDateCreate), '%minute%' => date("i", $iDateCreate), '%second%' => date("s", $iDateCreate), '%login%' => '', '%blog%' => '', '%id%' => $oTopic->getId(), '%title%' => $oTopic->getSlug(), '%type%' => $oTopic->getType()); /** * Получаем связанные данные только если в этом есть необходимость */ if (strpos($sUrlMask, '%blog%') !== false) { if (!($oBlog = $oTopic->GetBlog())) { $oBlog = $this->Blog_GetBlogById($oTopic->getBlogId()); } if ($oBlog) { if ($oBlog->getType() == 'personal') { $sUrlMask = str_replace('%blog%', '%login%', $sUrlMask); } else { $aReplace['%blog%'] = $oBlog->getUrl(); } } } if (strpos($sUrlMask, '%login%') !== false) { if (!($oUser = $oTopic->GetUser())) { $oUser = $this->User_GetUserById($oTopic->getUserId()); } if ($oUser) { $aReplace['%login%'] = $oUser->getLogin(); } } $sUrl = strtr($sUrlMask, $aReplace); return $bAbsolute ? Router::GetPathRootWeb() . '/' . $sUrl : $sUrl; }
/** * Обновляет топик * * @param ModuleTopic_EntityTopic $oTopic Объект топика * @return bool */ public function UpdateTopic(ModuleTopic_EntityTopic $oTopic) { /** * Получаем топик ДО изменения */ $oTopicOld = $this->GetTopicById($oTopic->getId()); $oTopic->setDateEdit(date("Y-m-d H:i:s")); if ($this->oMapperTopic->UpdateTopic($oTopic)) { /** * Если топик изменил видимость(publish) или локацию (BlogId) или список тегов */ if ($oTopic->getPublish() != $oTopicOld->getPublish() || $oTopic->getBlogId() != $oTopicOld->getBlogId() || $oTopic->getTags() != $oTopicOld->getTags()) { /** * Обновляем теги */ $this->DeleteTopicTagsByTopicId($oTopic->getId()); if ($oTopic->getPublish() and $oTopic->getTags()) { $aTags = explode(',', $oTopic->getTags()); foreach ($aTags as $sTag) { $oTag = Engine::GetEntity('Topic_TopicTag'); $oTag->setTopicId($oTopic->getId()); $oTag->setUserId($oTopic->getUserId()); $oTag->setBlogId($oTopic->getBlogId()); $oTag->setText($sTag); $this->AddTopicTag($oTag); } } } if ($oTopic->getPublish() != $oTopicOld->getPublish()) { /** * Обновляем избранное */ $this->SetFavouriteTopicPublish($oTopic->getId(), $oTopic->getPublish()); /** * Удаляем комментарий топика из прямого эфира */ if ($oTopic->getPublish() == 0) { $this->Comment_DeleteCommentOnlineByTargetId($oTopic->getId(), 'topic'); } /** * Изменяем видимость комментов */ $this->Comment_SetCommentsPublish($oTopic->getId(), 'topic', $oTopic->getPublish()); } //чистим зависимые кеши $this->Cache_Clean(Zend_Cache::CLEANING_MODE_MATCHING_TAG, array('topic_update', "topic_update_user_{$oTopic->getUserId()}")); $this->Cache_Delete("topic_{$oTopic->getId()}"); return true; } return false; }
/** * Обновляет контент топика * * @param ModuleTopic_EntityTopic $oTopic Объект топика * @return bool */ public function UpdateTopicContent(ModuleTopic_EntityTopic $oTopic) { $sql = "UPDATE " . Config::Get('db.table.topic_content') . "\n\t\t\tSET \t\t\t\t\n\t\t\t\ttopic_text= ?,\n\t\t\t\ttopic_text_short= ?,\n\t\t\t\ttopic_text_source= ?,\n\t\t\t\ttopic_extra= ?\n\t\t\tWHERE\n\t\t\t\ttopic_id = ?d\n\t\t"; $res = $this->oDb->query($sql, $oTopic->getText(), $oTopic->getTextShort(), $oTopic->getTextSource(), $oTopic->getExtra(), $oTopic->getId()); return $this->IsSuccessful($res); }
/** * Присоединение фотографий к фотосету топика * * @param ModuleTopic_EntityTopic $oTopic * @param string $sTargetTmp * * @return bool */ public function attachTmpPhotoToTopic($oTopic, $sTargetTmp) { if ($sTargetTmp) { $sql = "\n UPDATE ?_topic_photo\n SET topic_id=?d, target_tmp=NULL\n WHERE target_tmp=?\n "; return $this->oDb->query($sql, $oTopic->getId(), $sTargetTmp) !== false; } return true; }
/** * Show topic * * @return string|null */ protected function EventShowTopic() { $this->sMenuHeadItemSelect = 'index'; $sBlogUrl = ''; $sTopicUrlMask = R::GetTopicUrlMask(); if ($this->oCurrentTopic) { $this->oCurrentBlog = $this->oCurrentTopic->getBlog(); if ($this->oCurrentBlog) { $sBlogUrl = $this->oCurrentBlog->getUrl(); } $this->sMenuItemSelect = 'blog'; } else { if ($this->GetParamEventMatch(0, 1)) { // из коллективного блога $sBlogUrl = $this->sCurrentEvent; $iTopicId = $this->GetParamEventMatch(0, 1); $this->sMenuItemSelect = 'blog'; } else { // из персонального блога $iTopicId = $this->GetEventMatch(1); $this->sMenuItemSelect = 'log'; } // * Проверяем есть ли такой топик if (!$iTopicId || !($this->oCurrentTopic = E::ModuleTopic()->GetTopicById($iTopicId))) { return parent::EventNotFound(); } } if (!$this->oCurrentTopic->getBlog()) { // Этого быть не должно, но если вдруг, то надо отработать return parent::EventNotFound(); } $this->sMenuSubItemSelect = ''; // Trusted user is admin or owner of topic if ($this->oUserCurrent && ($this->oUserCurrent->isAdministrator() || $this->oUserCurrent->isModerator() || $this->oUserCurrent->getId() == $this->oCurrentTopic->getUserId())) { $bTrustedUser = true; } else { $bTrustedUser = false; } if (!$bTrustedUser) { // Topic with future date if ($this->oCurrentTopic->getDate() > date('Y-m-d H:i:s')) { return parent::EventNotFound(); } // * Проверяем права на просмотр топика-черновика if (!$this->oCurrentTopic->getPublish()) { if (!Config::Get('module.topic.draft_link')) { return parent::EventNotFound(); } else { // Если режим просмотра по прямой ссылке включен, то проверяем параметры $bOk = false; if ($sDraftCode = F::GetRequestStr('draft', null, 'get')) { if (strpos($sDraftCode, ':')) { list($nUser, $sHash) = explode(':', $sDraftCode); if ($this->oCurrentTopic->GetUserId() == $nUser && $this->oCurrentTopic->getTextHash() == $sHash) { $bOk = true; } } } if (!$bOk) { return parent::EventNotFound(); } } } } // Если номер топика правильный, но URL блога неверный, то корректируем его и перенаправляем на нужный адрес if ($sBlogUrl !== '' && $this->oCurrentTopic->getBlog()->getUrl() !== $sBlogUrl) { R::Location($this->oCurrentTopic->getUrl()); } // Если запросили топик с определенной маской, не указаным названием блога, // но ссылка на топик и ЧПУ url разные, и это не запрос RSS // то перенаправляем на страницу для вывода топика (во избежание дублирования контента по разным URL) if ($sTopicUrlMask && $sBlogUrl == '' && $this->oCurrentTopic->getUrl() != R::GetPathWebCurrent() . (substr($this->oCurrentTopic->getUrl(), -1) === '/' ? '/' : '') && substr(R::RealUrl(true), 0, 4) !== 'rss/') { R::Location($this->oCurrentTopic->getUrl()); } // Checks rights to show content from the blog if (!$this->oCurrentTopic->getBlog()->CanReadBy($this->oUserCurrent)) { E::ModuleMessage()->AddErrorSingle(E::ModuleLang()->Get('acl_cannot_show_content'), E::ModuleLang()->Get('not_access')); return R::Action('error'); } // Обрабатываем добавление коммента if (isset($_REQUEST['submit_comment'])) { $this->SubmitComment(); } // Достаём комменты к топику if (!Config::Get('module.comment.nested_page_reverse') && Config::Get('module.comment.use_nested') && Config::Get('module.comment.nested_per_page')) { $iPageDef = ceil(E::ModuleComment()->GetCountCommentsRootByTargetId($this->oCurrentTopic->getId(), 'topic') / Config::Get('module.comment.nested_per_page')); } else { $iPageDef = 1; } $iPage = intval(F::GetRequest('cmtpage', 0)); if ($iPage < 1) { $iPage = $iPageDef; } $aReturn = E::ModuleComment()->GetCommentsByTargetId($this->oCurrentTopic, 'topic', $iPage, Config::Get('module.comment.nested_per_page')); $iMaxIdComment = $aReturn['iMaxIdComment']; /** @var ModuleComment_EntityComment[] $aComments */ $aComments = $aReturn['comments']; if ($aComments && $iMaxIdComment && isset($aComments[$iMaxIdComment])) { $sLastCommentDate = $aComments[$iMaxIdComment]->getDate(); } else { $sLastCommentDate = null; } // Если используется постраничность для комментариев - формируем ее if (Config::Get('module.comment.use_nested') && Config::Get('module.comment.nested_per_page')) { $aPaging = E::ModuleViewer()->MakePaging($aReturn['count'], $iPage, Config::Get('module.comment.nested_per_page'), Config::Get('pagination.pages.count'), ''); if (!Config::Get('module.comment.nested_page_reverse') && $aPaging) { // переворачиваем страницы в обратном порядке $aPaging['aPagesLeft'] = array_reverse($aPaging['aPagesLeft']); $aPaging['aPagesRight'] = array_reverse($aPaging['aPagesRight']); } E::ModuleViewer()->Assign('aPagingCmt', $aPaging); } // issue 253 {@link https://github.com/altocms/altocms/issues/253} // Запрещаем оставлять комментарии к топику-черновику // if ($this->oUserCurrent) { if ($this->oUserCurrent && (int) $this->oCurrentTopic->getPublish()) { $bAllowToComment = E::ModuleBlog()->GetBlogsAllowTo('comment', $this->oUserCurrent, $this->oCurrentTopic->getBlog()->GetId(), true); } else { $bAllowToComment = false; } // Отмечаем прочтение топика if ($this->oUserCurrent) { $oTopicRead = E::ModuleTopic()->GetTopicRead($this->oCurrentTopic->getId(), $this->oUserCurrent->getid()); if (!$oTopicRead) { /** @var ModuleTopic_EntityTopicRead $oTopicRead */ $oTopicRead = E::GetEntity('Topic_TopicRead'); $oTopicRead->setTopicId($this->oCurrentTopic->getId()); $oTopicRead->setUserId($this->oUserCurrent->getId()); $oTopicRead->setCommentCountLast($this->oCurrentTopic->getCountComment()); $oTopicRead->setCommentIdLast($iMaxIdComment); $oTopicRead->setDateRead(F::Now()); E::ModuleTopic()->AddTopicRead($oTopicRead); } else { if ($oTopicRead->getCommentCountLast() != $this->oCurrentTopic->getCountComment() || $oTopicRead->getCommentIdLast() != $iMaxIdComment || !is_null($sLastCommentDate) && $oTopicRead->getDateRead() <= $sLastCommentDate) { $oTopicRead->setCommentCountLast($this->oCurrentTopic->getCountComment()); $oTopicRead->setCommentIdLast($iMaxIdComment); $oTopicRead->setDateRead(F::Now()); E::ModuleTopic()->UpdateTopicRead($oTopicRead); } } } // Выставляем SEO данные $sTextSeo = strip_tags($this->oCurrentTopic->getText()); E::ModuleViewer()->SetHtmlDescription(F::CutText($sTextSeo, Config::Get('view.html.description_max_words'))); E::ModuleViewer()->SetHtmlKeywords($this->oCurrentTopic->getTags()); E::ModuleViewer()->SetHtmlCanonical($this->oCurrentTopic->getUrl()); // Вызов хуков E::ModuleHook()->Run('topic_show', array('oTopic' => $this->oCurrentTopic)); // Загружаем переменные в шаблон E::ModuleViewer()->Assign('oTopic', $this->oCurrentTopic); E::ModuleViewer()->Assign('aComments', $aComments); E::ModuleViewer()->Assign('iMaxIdComment', $iMaxIdComment); E::ModuleViewer()->Assign('bAllowToComment', $bAllowToComment); // Устанавливаем title страницы E::ModuleViewer()->AddHtmlTitle($this->oCurrentTopic->getBlog()->getTitle()); E::ModuleViewer()->AddHtmlTitle($this->oCurrentTopic->getTitle()); E::ModuleViewer()->SetHtmlRssAlternate(R::GetPath('rss') . 'comments/' . $this->oCurrentTopic->getId() . '/', $this->oCurrentTopic->getTitle()); // Устанавливаем шаблон вывода $this->SetTemplateAction('topic'); // Additional tags for <head> $aHeadTags = $this->_getHeadTags($this->oCurrentTopic); if ($aHeadTags) { E::ModuleViewer()->SetHtmlHeadTags($aHeadTags); } return null; }
/** * Проверка на соответсвие коментария родительскому коментарию * * @param ModuleTopic_EntityTopic $oTopic * @param string $sText * @param ModuleComment_EntityComment $oCommentParent * * @return bool result */ protected function CheckParentComment($oTopic, $sText, $oCommentParent) { $sParentId = 0; if ($oCommentParent) { $sParentId = $oCommentParent->GetCommentId(); } $bOk = true; /** * Проверям на какой коммент отвечаем */ if (!func_check($sParentId, 'id')) { $this->Message_AddErrorSingle($this->Lang_Get('common.error.system.base'), $this->Lang_Get('common.error.error')); $bOk = false; } if ($sParentId) { /** * Проверяем существует ли комментарий на который отвечаем */ if (!$oCommentParent) { $this->Message_AddErrorSingle($this->Lang_Get('common.error.system.base'), $this->Lang_Get('common.error.error')); $bOk = false; } /** * Проверяем из одного топика ли новый коммент и тот на который отвечаем */ if ($oCommentParent->getTargetId() != $oTopic->getId()) { $this->Message_AddErrorSingle($this->Lang_Get('common.error.system.base'), $this->Lang_Get('common.error.error')); $bOk = false; } } else { $sParentId = null; } /** * Проверка на дублирующий коммент */ if ($this->Comment_GetCommentUnique($oTopic->getId(), 'topic', $this->oUserCurrent->getId(), $sParentId, md5($sText))) { $this->Message_AddErrorSingle($this->Lang_Get('topic.comments.notices.spam'), $this->Lang_Get('common.error.error')); $bOk = false; } $this->Hook_Run('comment_check_parent', array('oTopic' => $oTopic, 'sText' => $sText, 'oCommentParent' => $oCommentParent, 'bOk' => &$bOk)); return $bOk; }
/** * Обновляет контент топика * * @param ModuleTopic_EntityTopic $oTopic Объект топика * @return bool */ public function UpdateTopicContent(ModuleTopic_EntityTopic $oTopic) { $sql = "UPDATE " . Config::Get('db.table.topic_content') . "\n SET\n topic_text= ?,\n topic_text_short= ?,\n topic_text_source= ?,\n topic_extra= ?\n WHERE\n topic_id = ?d\n "; if ($this->oDb->query($sql, $oTopic->getText(), $oTopic->getTextShort(), $oTopic->getTextSource(), $oTopic->getExtra(), $oTopic->getId())) { return true; } return false; }
/** * Проверяет может ли пользователь голосовать за конкретный топик * * @param ModuleUser_EntityUser $oUser Пользователь * @param ModuleTopic_EntityTopic $oTopic Топик * @param int $iValue Направление голосования * @return bool */ public function CanVoteTopic($oUser, $oTopic, $iValue) { $that = $this; // fix for PHP < 5.4 return $this->Rbac_IsAllowUser($oUser, 'vote_topic', array('callback' => function ($oUser, $aParams) use($that, $oTopic, $iValue) { if (!$oUser) { return false; } /** * Голосует автор топика? */ if ($oTopic->getUserId() == $oUser->getId()) { return $that->Lang_Get('vote.notices.error_self'); } /** * Пользователь уже голосовал? */ if ($oTopicVote = $that->Vote_GetVote($oTopic->getId(), 'topic', $oUser->getId())) { return $that->Lang_Get('vote.notices.error_already_voted'); } /** * Время голосования истекло? */ if (strtotime($oTopic->getDatePublish()) <= time() - Config::Get('acl.vote.topic.limit_time')) { return $that->Lang_Get('vote.notices.error_time'); } /** * Ограничение по рейтингу */ if ($iValue != 0 and $oUser->getRating() < Config::Get('acl.vote.topic.rating')) { return $that->Lang_Get('vote.notices.error_acl'); } return true; })); }
protected function updateAccessLevel(ModuleTopic_EntityTopic $oTopic) { $sql = 'UPDATE ' . Config::Get('db.table.topic') . ' SET access_level = ?d WHERE topic_id = ?d '; if ($this->oDb->query($sql, $oTopic->getAccessLevel(), $oTopic->getId()) !== null) { return true; } return false; }