1
0
Fork 0
mirror of https://github.com/Oreolek/ifhub.club.git synced 2024-07-03 06:55:03 +03:00
This commit is contained in:
Mzhelskiy Maxim 2009-05-29 15:32:37 +00:00
parent 9413427b2f
commit 548bd31699
9 changed files with 586 additions and 156 deletions

View file

@ -35,6 +35,101 @@ class LsBlog extends Module {
$this->oMapperBlog->SetUserCurrent($this->User_GetUserCurrent()); $this->oMapperBlog->SetUserCurrent($this->User_GetUserCurrent());
$this->oUserCurrent=$this->User_GetUserCurrent(); $this->oUserCurrent=$this->User_GetUserCurrent();
} }
/**
* Получает дополнительные данные(объекты) для блогов по их ID
*
*/
public function GetBlogsAdditionalData($aBlogId,$aAllowData=array('vote','owner')) {
func_array_simpleflip($aAllowData);
if (!is_array($aBlogId)) {
$aBlogId=array($aBlogId);
}
/**
* Получаем блоги
*/
$aBlogs=$this->GetBlogsByArrayId($aBlogId);
/**
* Формируем ID дополнительных данных, которые нужно получить
*/
$aUserId=array();
foreach ($aBlogs as $oBlog) {
if (isset($aAllowData['owner'])) {
$aUserId[]=$oBlog->getOwnerId();
}
}
/**
* Получаем дополнительные данные
*/
$aUsers=isset($aAllowData['owner']) && is_array($aAllowData['owner']) ? $this->User_GetUsersAdditionalData($aUserId,$aAllowData['owner']) : $this->User_GetUsersAdditionalData($aUserId);
/**
* Добавляем данные к результату - списку блогов
*/
foreach ($aBlogs as $oBlog) {
if (isset($aUsers[$oBlog->getOwnerId()])) {
$oBlog->setOwner($aUsers[$oBlog->getOwnerId()]);
} else {
$oBlog->setOwner(null); // или $oBlog->setOwner(new UserEntity_User());
}
/**
* Права на блог
*/
$oBlog->setUserIsAdministrator(false);
$oBlog->setUserIsModerator(false);
if ($this->oUserCurrent and $oBlogUser=$this->GetRelationBlogUserByBlogIdAndUserId($oBlog->getId(),$this->oUserCurrent->getId())) {
if ($oBlogUser->getIsAdministrator()) {
$oBlog->setUserIsAdministrator(true);
}
if ($oBlogUser->getIsModerator()) {
$oBlog->setUserIsModerator(true);
}
}
/**
*
*/
}
return $aBlogs;
}
/**
* Список блогов по ID
*
* @param array $aUserId
*/
public function GetBlogsByArrayId($aBlogId) {
if (!is_array($aBlogId)) {
$aBlogId=array($aBlogId);
}
$aBlogId=array_unique($aBlogId);
$aBlogs=array();
/**
* Делаем мульти-запрос к кешу
*/
$aCacheKeys=func_array_change_value($aBlogId,'blog_');
if (false !== ($data = $this->Cache_Get($aCacheKeys))) {
/**
* проверяем что досталось из кеша
*/
foreach ($aCacheKeys as $sKey ) {
if (isset($data[$sKey])) {
$aBlogs[$data[$sKey]->getId()]=$data[$sKey];
}
}
}
/**
* Смотрим каких блогов не было в кеше и делаем запрос в БД
*/
$aBlogIdNeedQuery=array_diff($aBlogId,array_keys($aBlogs));
if ($data = $this->oMapperBlog->GetBlogsByArrayId($aBlogIdNeedQuery)) {
foreach ($data as $oBlog) {
/**
* Добавляем к результату и сохраняем в кеш
*/
$aBlogs[$oBlog->getId()]=$oBlog;
$this->Cache_Set($oBlog, "blog_{$oBlog->getId()}", array("blog_update_{$oBlog->getId()}"), 60*60*24*4);
}
}
return $aBlogs;
}
/** /**
* Получить персональный блог юзера * Получить персональный блог юзера
* *
@ -51,7 +146,11 @@ class LsBlog extends Module {
* @return unknown * @return unknown
*/ */
public function GetBlogById($sBlogId) { public function GetBlogById($sBlogId) {
return $this->oMapperBlog->GetBlogById($sBlogId); $aBlogs=$this->GetBlogsAdditionalData($sId);
if (isset($aBlogs[$sId])) {
return $aBlogs[$sId];
}
return null;
} }
/** /**
* Получить блог по УРЛу * Получить блог по УРЛу
@ -257,7 +356,7 @@ class LsBlog extends Module {
if ($aBlogUser=$this->oMapperBlog->GetRelationBlogUsers($aFilter)) { if ($aBlogUser=$this->oMapperBlog->GetRelationBlogUsers($aFilter)) {
return $aBlogUser[0]; return $aBlogUser[0];
} }
return false; return null;
} }
/** /**
* Список модеро вблога * Список модеро вблога

View file

@ -60,22 +60,12 @@ class BlogEntity_Blog extends Entity
return $this->_aData['blog_avatar_type']; return $this->_aData['blog_avatar_type'];
} }
public function getUserLogin() {
return $this->_aData['user_login'];
public function getOwner() {
return $this->_aData['owner'];
} }
public function getUserProfileAvatar() {
return $this->_aData['user_profile_avatar'];
}
public function getUserProfileAvatarType() {
return $this->_aData['user_profile_avatar_type'];
}
public function getUserProfileAvatarPath($iSize=100) {
if ($this->getUserProfileAvatar()) {
return DIR_WEB_ROOT.DIR_UPLOADS_IMAGES.'/'.$this->getOwnerId().'/avatar_'.$iSize.'x'.$iSize.'.'.$this->getUserProfileAvatarType();
} else {
return DIR_STATIC_SKIN.'/images/avatar_'.$iSize.'x'.$iSize.'.jpg';
}
}
public function getUserIsVote() { public function getUserIsVote() {
return $this->_aData['user_is_vote']; return $this->_aData['user_is_vote'];
} }
@ -89,18 +79,23 @@ class BlogEntity_Blog extends Entity
return DIR_STATIC_SKIN.'/images/avatar_blog_'.$iSize.'x'.$iSize.'.gif'; return DIR_STATIC_SKIN.'/images/avatar_blog_'.$iSize.'x'.$iSize.'.gif';
} }
} }
public function getCurrentUserIsJoin() { public function getUserIsJoin() {
return $this->_aData['current_user_is_join']; return $this->_aData['user_is_join'];
}
public function getUserIsAdministrator() {
return $this->_aData['user_is_administrator'];
}
public function getUserIsModerator() {
return $this->_aData['user_is_moderator'];
} }
public function getUrlFull() { public function getUrlFull() {
if ($this->getType()=='personal') { if ($this->getType()=='personal') {
return DIR_WEB_ROOT.'/'.ROUTE_PAGE_MY.'/'.$this->getUserLogin().'/'; return DIR_WEB_ROOT.'/'.ROUTE_PAGE_MY.'/'.$this->getOwner()->getLogin().'/';
} else { } else {
return DIR_WEB_ROOT.'/'.ROUTE_PAGE_BLOG.'/'.$this->getUrl().'/'; return DIR_WEB_ROOT.'/'.ROUTE_PAGE_BLOG.'/'.$this->getUrl().'/';
} }
} }
public function setId($data) { public function setId($data) {
$this->_aData['blog_id']=$data; $this->_aData['blog_id']=$data;
@ -144,5 +139,18 @@ class BlogEntity_Blog extends Entity
public function setAvatarType($data) { public function setAvatarType($data) {
$this->_aData['blog_avatar_type']=$data; $this->_aData['blog_avatar_type']=$data;
} }
public function setOwner($data) {
$this->_aData['owner']=$data;
}
public function setUserIsAdministrator($data) {
$this->_aData['user_is_administrator']=$data;
}
public function setUserIsModerator($data) {
$this->_aData['user_is_moderator']=$data;
}
public function setUserIsJoin($data) {
$this->_aData['user_is_join']=$data;
}
} }
?> ?>

View file

@ -65,7 +65,27 @@ class Mapper_Blog extends Mapper {
return false; return false;
} }
public function GetBlogsByArrayId($aArrayId) {
if (!is_array($aArrayId) or count($aArrayId)==0) {
return array();
}
$sql = "SELECT
b.*
FROM
".DB_TABLE_BLOG." as b
WHERE
b.blog_id IN(?a)
ORDER BY FIELD(b.blog_id,?a) ";
$aBlogs=array();
if ($aRows=$this->oDb->select($sql,$aArrayId,$aArrayId)) {
foreach ($aRows as $aBlog) {
$aBlogs[]=new BlogEntity_Blog($aBlog);
}
}
return $aBlogs;
}
public function AddRelationBlogUser(BlogEntity_BlogUser $oBlogUser) { public function AddRelationBlogUser(BlogEntity_BlogUser $oBlogUser) {
$sql = "INSERT INTO ".DB_TABLE_BLOG_USER." $sql = "INSERT INTO ".DB_TABLE_BLOG_USER."
(blog_id, (blog_id,

View file

@ -39,7 +39,7 @@ class LsTopic extends Module {
* Получает дополнительные данные(объекты) для топиков по их ID * Получает дополнительные данные(объекты) для топиков по их ID
* *
*/ */
public function GetTopicsAdditionalData($aTopicId,$aAllowData=array('user','blog','content','vote')) { public function GetTopicsAdditionalData($aTopicId,$aAllowData=array('user','blog','vote','favourite','comment_new')) {
func_array_simpleflip($aAllowData); func_array_simpleflip($aAllowData);
if (!is_array($aTopicId)) { if (!is_array($aTopicId)) {
$aTopicId=array($aTopicId); $aTopicId=array($aTopicId);
@ -52,7 +52,7 @@ class LsTopic extends Module {
* Формируем ID дополнительных данных, которые нужно получить * Формируем ID дополнительных данных, которые нужно получить
*/ */
$aUserId=array(); $aUserId=array();
$aBlogId=array(); $aBlogId=array();
foreach ($aTopics as $oTopic) { foreach ($aTopics as $oTopic) {
if (isset($aAllowData['user'])) { if (isset($aAllowData['user'])) {
$aUserId[]=$oTopic->getUserId(); $aUserId[]=$oTopic->getUserId();
@ -64,8 +64,22 @@ class LsTopic extends Module {
/** /**
* Получаем дополнительные данные * Получаем дополнительные данные
*/ */
$aTopicsVote=array();
$aFavouriteTopics=array();
$aTopicsQuestionVote=array();
$aCountCommentNew=array();
$aUsers=isset($aAllowData['user']) && is_array($aAllowData['user']) ? $this->User_GetUsersAdditionalData($aUserId,$aAllowData['user']) : $this->User_GetUsersAdditionalData($aUserId); $aUsers=isset($aAllowData['user']) && is_array($aAllowData['user']) ? $this->User_GetUsersAdditionalData($aUserId,$aAllowData['user']) : $this->User_GetUsersAdditionalData($aUserId);
$aBlogs=isset($aAllowData['blog']) && is_array($aAllowData['blog']) ? $this->Blog_GetBlogsAdditionalData($aBlogId,$aAllowData['blog']) : $this->Blog_GetBlogsAdditionalData($aBlogId); $aBlogs=isset($aAllowData['blog']) && is_array($aAllowData['blog']) ? $this->Blog_GetBlogsAdditionalData($aBlogId,$aAllowData['blog']) : $this->Blog_GetBlogsAdditionalData($aBlogId);
if (isset($aAllowData['vote'])) {
$aTopicsVote=$this->GetTopicsVoteByArray($aTopicId,$this->oUserCurrent->getId());
$aTopicsQuestionVote=$this->GetTopicsQuestionVoteByArray($aTopicId,$this->oUserCurrent->getId());
}
if (isset($aAllowData['favourite'])) {
$aFavouriteTopics=$this->GetFavouriteTopicsByArray($aTopicId,$this->oUserCurrent->getId());
}
if (isset($aAllowData['comment_new'])) {
$aCountCommentNew=$this->GetTopicsReadByArray($aTopicId,$this->oUserCurrent->getId());
}
/** /**
* Добавляем данные к результату - списку топиков * Добавляем данные к результату - списку топиков
*/ */
@ -80,6 +94,27 @@ class LsTopic extends Module {
} else { } else {
$oTopic->setBlog(null); // или $oTopic->setBlog(new BlogEntity_Blog()); $oTopic->setBlog(null); // или $oTopic->setBlog(new BlogEntity_Blog());
} }
if (isset($aTopicsVote[$oTopic->getId()])) {
$oTopic->setUserIsVote(true);
$oTopic->setUserVoteDelta($aTopicsVote[$oTopic->getId()]->getDelta());
} else {
$oTopic->setUserIsVote(false);
}
if (isset($aFavouriteTopics[$oTopic->getId()])) {
$oTopic->setIsFavourite(true);
} else {
$oTopic->setIsFavourite(false);
}
if (isset($aTopicsQuestionVote[$oTopic->getId()])) {
$oTopic->setUserQuestionIsVote(true);
} else {
$oTopic->setUserQuestionIsVote(false);
}
if (isset($aCountCommentNew[$oTopic->getId()])) {
$oTopic->setCountCommentNew($oTopic->getCountComment()-$aCountCommentNew[$oTopic->getId()]->getCommentCountLast());
} else {
$oTopic->setCountCommentNew(0);
}
} }
return $aTopics; return $aTopics;
} }
@ -189,8 +224,8 @@ class LsTopic extends Module {
*/ */
public function GetTopicById($sId) { public function GetTopicById($sId) {
$aTopics=$this->GetTopicsAdditionalData($sId); $aTopics=$this->GetTopicsAdditionalData($sId);
if (count($aTopics)>0) { if (isset($aTopics[$sId])) {
return $aTopics[0]; return $aTopics[$sId];
} }
return null; return null;
} }
@ -203,6 +238,7 @@ class LsTopic extends Module {
if (!is_array($aTopicId)) { if (!is_array($aTopicId)) {
$aTopicId=array($aTopicId); $aTopicId=array($aTopicId);
} }
$aTopicId=array_unique($aTopicId);
$aTopics=array(); $aTopics=array();
/** /**
* Делаем мульти-запрос к кешу * Делаем мульти-запрос к кешу
@ -222,7 +258,7 @@ class LsTopic extends Module {
* Смотрим каких топиков не было в кеше и делаем запрос в БД * Смотрим каких топиков не было в кеше и делаем запрос в БД
*/ */
$aTopicIdNeedQuery=array_diff($aTopicId,array_keys($aTopics)); $aTopicIdNeedQuery=array_diff($aTopicId,array_keys($aTopics));
if ($data = $this->oMapper->GetTopicsByArrayId($aTopicIdNeedQuery)) { if ($data = $this->oMapperTopic->GetTopicsByArrayId($aTopicIdNeedQuery)) {
foreach ($data as $oTopic) { foreach ($data as $oTopic) {
/** /**
* Добавляем к результату и сохраняем в кеш * Добавляем к результату и сохраняем в кеш
@ -244,9 +280,10 @@ class LsTopic extends Module {
*/ */
public function GetTopicsFavouriteByUserId($sUserId,$iCurrPage,$iPerPage) { public function GetTopicsFavouriteByUserId($sUserId,$iCurrPage,$iPerPage) {
if (false === ($data = $this->Cache_Get("topic_favourite_user_{$sUserId}_{$iCurrPage}_{$iPerPage}"))) { if (false === ($data = $this->Cache_Get("topic_favourite_user_{$sUserId}_{$iCurrPage}_{$iPerPage}"))) {
$data = array('collection'=>$this->GetTopicsAdditionalData($this->oMapperTopic->GetTopicsFavouriteByUserId($sUserId,$iCount,$iCurrPage,$iPerPage)),'count'=>$iCount); $data = array('collection'=>$this->oMapperTopic->GetTopicsFavouriteByUserId($sUserId,$iCount,$iCurrPage,$iPerPage),'count'=>$iCount);
$this->Cache_Set($data, "topic_favourite_user_{$sUserId}_{$iCurrPage}_{$iPerPage}", array('topic_update',"favourite_change_user_{$sUserId}"), 60*60*24*1); $this->Cache_Set($data, "topic_favourite_user_{$sUserId}_{$iCurrPage}_{$iPerPage}", array('topic_update',"favourite_change_user_{$sUserId}"), 60*60*24*1);
} }
$data['collection']=$this->GetTopicsAdditionalData($data['collection']);
return $data; return $data;
} }
/** /**
@ -266,9 +303,10 @@ class LsTopic extends Module {
protected function GetTopicsByFilter($aFilter,$iPage,$iPerPage) { protected function GetTopicsByFilter($aFilter,$iPage,$iPerPage) {
$s=serialize($aFilter); $s=serialize($aFilter);
if (false === ($data = $this->Cache_Get("topic_filter_{$s}_{$iPage}_{$iPerPage}"))) { if (false === ($data = $this->Cache_Get("topic_filter_{$s}_{$iPage}_{$iPerPage}"))) {
$data = array('collection'=>$this->GetTopicsAdditionalData($this->oMapperTopic->GetTopics($aFilter,$iCount,$iPage,$iPerPage)),'count'=>$iCount); $data = array('collection'=>$this->oMapperTopic->GetTopics($aFilter,$iCount,$iPage,$iPerPage),'count'=>$iCount);
$this->Cache_Set($data, "topic_filter_{$s}_{$iPage}_{$iPerPage}", array('topic_update','topic_new'), 60*60*24*3); $this->Cache_Set($data, "topic_filter_{$s}_{$iPage}_{$iPerPage}", array('topic_update','topic_new'), 60*60*24*3);
} }
$data['collection']=$this->GetTopicsAdditionalData($data['collection']);
return $data; return $data;
} }
@ -533,9 +571,10 @@ class LsTopic extends Module {
*/ */
public function GetTopicsRatingByDate($sDate,$iLimit=20) { public function GetTopicsRatingByDate($sDate,$iLimit=20) {
if (false === ($data = $this->Cache_Get("topic_rating_{$sDate}_{$iLimit}"))) { if (false === ($data = $this->Cache_Get("topic_rating_{$sDate}_{$iLimit}"))) {
$data = $this->GetTopicsAdditionalData($this->oMapperTopic->GetTopicsRatingByDate($sDate,$iLimit)); $data = $this->oMapperTopic->GetTopicsRatingByDate($sDate,$iLimit);
$this->Cache_Set($data, "topic_rating_{$sDate}_{$iLimit}", array('topic_update'), 60*60*24*2); $this->Cache_Set($data, "topic_rating_{$sDate}_{$iLimit}", array('topic_update'), 60*60*24*2);
} }
$data=$this->GetTopicsAdditionalData($data);
return $data; return $data;
} }
/** /**
@ -632,9 +671,10 @@ class LsTopic extends Module {
*/ */
public function GetTopicsByTag($sTag,$iPage,$iPerPage) { public function GetTopicsByTag($sTag,$iPage,$iPerPage) {
if (false === ($data = $this->Cache_Get("topic_tag_{$sTag}_{$iPage}_{$iPerPage}"))) { if (false === ($data = $this->Cache_Get("topic_tag_{$sTag}_{$iPage}_{$iPerPage}"))) {
$data = array('collection'=>$this->GetTopicsAdditionalData($this->oMapperTopic->GetTopicsByTag($sTag,$iCount,$iPage,$iPerPage)),'count'=>$iCount); $data = array('collection'=>$this->oMapperTopic->GetTopicsByTag($sTag,$iCount,$iPage,$iPerPage),'count'=>$iCount);
$this->Cache_Set($data, "topic_tag_{$sTag}_{$iPage}_{$iPerPage}", array('topic_update','topic_new'), 60*15); $this->Cache_Set($data, "topic_tag_{$sTag}_{$iPage}_{$iPerPage}", array('topic_update','topic_new'), 60*15);
} }
$data['collection']=$this->GetTopicsAdditionalData($data['collection']);
return $data; return $data;
} }
/** /**
@ -658,7 +698,52 @@ class LsTopic extends Module {
* @return unknown * @return unknown
*/ */
public function GetTopicVote($sTopicId,$sUserId) { public function GetTopicVote($sTopicId,$sUserId) {
return $this->oMapperTopic->GetTopicVote($sTopicId,$sUserId); $data=$this->GetTopicsVoteByArray($sTopicId,$sUserId);
if (isset($data[$sTopicId])) {
return $data[$sTopicId];
}
return null;
}
/**
* Получить список голосований за топик по списку айдишников
*
* @param unknown_type $aTopicId
*/
public function GetTopicsVoteByArray($aTopicId,$sUserId) {
if (!is_array($aTopicId)) {
$aTopicId=array($aTopicId);
}
$aTopicId=array_unique($aTopicId);
$aTopicsVote=array();
/**
* Делаем мульти-запрос к кешу
*/
$aCacheKeys=func_array_change_value($aTopicId,'topic_vote_','_'.$sUserId);
if (false !== ($data = $this->Cache_Get($aCacheKeys))) {
/**
* проверяем что досталось из кеша
*/
foreach ($aCacheKeys as $sKey ) {
if (isset($data[$sKey])) {
$aTopicsVote[$data[$sKey]->getTopicId()]=$data[$sKey];
}
}
}
/**
* Смотрим каких топиков не было в кеше и делаем запрос в БД
*/
$aTopicIdNeedQuery=array_diff($aTopicId,array_keys($aTopicsVote));
if ($data = $this->oMapperTopic->GetTopicsVoteByArray($aTopicIdNeedQuery,$sUserId)) {
foreach ($data as $oTopicVote) {
/**
* Добавляем к результату и сохраняем в кеш
*/
$aTopicsVote[$oTopicVote->getTopicId()]=$oTopicVote;
$this->Cache_Set($oTopicVote, "topic_vote_{$oTopicVote->getTopicId()}_{$oTopicVote->getVoterId()}", array(), 60*60*24*4);
}
}
return $aTopicsVote;
} }
/** /**
* Увеличивает у топика число комментов * Увеличивает у топика число комментов
@ -678,7 +763,51 @@ class LsTopic extends Module {
* @return unknown * @return unknown
*/ */
public function GetFavouriteTopic($sTopicId,$sUserId) { public function GetFavouriteTopic($sTopicId,$sUserId) {
return $this->oMapperTopic->GetFavouriteTopic($sTopicId,$sUserId); $data=$this->GetFavouriteTopicsByArray($sTopicId,$sUserId);
if (isset($data[$sTopicId])) {
return $data[$sTopicId];
}
return null;
}
/**
* Получить список избранного по списку айдишников
*
* @param unknown_type $aTopicId
*/
public function GetFavouriteTopicsByArray($aTopicId,$sUserId) {
if (!is_array($aTopicId)) {
$aTopicId=array($aTopicId);
}
$aTopicId=array_unique($aTopicId);
$aFavouriteTopics=array();
/**
* Делаем мульти-запрос к кешу
*/
$aCacheKeys=func_array_change_value($aTopicId,'favourite_topic_','_'.$sUserId);
if (false !== ($data = $this->Cache_Get($aCacheKeys))) {
/**
* проверяем что досталось из кеша
*/
foreach ($aCacheKeys as $sKey ) {
if (isset($data[$sKey])) {
$aFavouriteTopics[$data[$sKey]->getTopicId()]=$data[$sKey];
}
}
}
/**
* Смотрим каких топиков не было в кеше и делаем запрос в БД
*/
$aTopicIdNeedQuery=array_diff($aTopicId,array_keys($aFavouriteTopics));
if ($data = $this->oMapperTopic->GetFavouriteTopicsByArray($aTopicIdNeedQuery,$sUserId)) {
foreach ($data as $oFavouriteTopic) {
/**
* Добавляем к результату и сохраняем в кеш
*/
$aFavouriteTopics[$oFavouriteTopic->getTopicId()]=$oFavouriteTopic;
$this->Cache_Set($oFavouriteTopic, "favourite_topic_{$oFavouriteTopic->getTopicId()}_{$oFavouriteTopic->getUserId()}", array(), 60*60*24*4);
}
}
return $aFavouriteTopics;
} }
/** /**
* Добавляет топик в избранное * Добавляет топик в избранное
@ -737,6 +866,46 @@ class LsTopic extends Module {
*/ */
public function GetTopicRead($sTopicId,$sUserId) { public function GetTopicRead($sTopicId,$sUserId) {
return $this->oMapperTopic->GetTopicRead($sTopicId,$sUserId); return $this->oMapperTopic->GetTopicRead($sTopicId,$sUserId);
}
/**
* Получить список просмотром/чтения топиков по списку айдишников
*
* @param unknown_type $aTopicId
*/
public function GetTopicsReadByArray($aTopicId,$sUserId) {
if (!is_array($aTopicId)) {
$aTopicId=array($aTopicId);
}
$aTopicId=array_unique($aTopicId);
$aTopicsRead=array();
/**
* Делаем мульти-запрос к кешу
*/
$aCacheKeys=func_array_change_value($aTopicId,'topic_read_','_'.$sUserId);
if (false !== ($data = $this->Cache_Get($aCacheKeys))) {
/**
* проверяем что досталось из кеша
*/
foreach ($aCacheKeys as $sKey ) {
if (isset($data[$sKey])) {
$aTopicsRead[$data[$sKey]->getTopicId()]=$data[$sKey];
}
}
}
/**
* Смотрим каких топиков не было в кеше и делаем запрос в БД
*/
$aTopicIdNeedQuery=array_diff($aTopicId,array_keys($aTopicsRead));
if ($data = $this->oMapperTopic->GetTopicsReadByArray($aTopicIdNeedQuery,$sUserId)) {
foreach ($data as $oTopicRead) {
/**
* Добавляем к результату и сохраняем в кеш
*/
$aTopicsRead[$oTopicRead->getTopicId()]=$oTopicRead;
$this->Cache_Set($oTopicRead, "topic_read_{$oTopicRead->getTopicId()}_{$oTopicRead->getUserId()}", array(), 60*60*24*4);
}
}
return $aTopicsRead;
} }
/** /**
* Проверяет голосовал ли юзер за топик-вопрос * Проверяет голосовал ли юзер за топик-вопрос
@ -746,7 +915,51 @@ class LsTopic extends Module {
* @return unknown * @return unknown
*/ */
public function GetTopicQuestionVote($sTopicId,$sUserId) { public function GetTopicQuestionVote($sTopicId,$sUserId) {
return $this->oMapperTopic->GetTopicQuestionVote($sTopicId,$sUserId); $data=$this->GetTopicsQuestionVoteByArray($sTopicId,$sUserId);
if (isset($data[$sTopicId])) {
return $data[$sTopicId];
}
return null;
}
/**
* Получить список голосований в топике-опросе по списку айдишников
*
* @param unknown_type $aTopicId
*/
public function GetTopicsQuestionVoteByArray($aTopicId,$sUserId) {
if (!is_array($aTopicId)) {
$aTopicId=array($aTopicId);
}
$aTopicId=array_unique($aTopicId);
$aTopicsQuestionVote=array();
/**
* Делаем мульти-запрос к кешу
*/
$aCacheKeys=func_array_change_value($aTopicId,'topic_question_vote_','_'.$sUserId);
if (false !== ($data = $this->Cache_Get($aCacheKeys))) {
/**
* проверяем что досталось из кеша
*/
foreach ($aCacheKeys as $sKey ) {
if (isset($data[$sKey])) {
$aTopicsQuestionVote[$data[$sKey]->getTopicId()]=$data[$sKey];
}
}
}
/**
* Смотрим каких топиков не было в кеше и делаем запрос в БД
*/
$aTopicIdNeedQuery=array_diff($aTopicId,array_keys($aTopicsQuestionVote));
if ($data = $this->oMapperTopic->GetTopicsQuestionVoteByArray($aTopicIdNeedQuery,$sUserId)) {
foreach ($data as $oTopicVote) {
/**
* Добавляем к результату и сохраняем в кеш
*/
$aTopicsQuestionVote[$oTopicVote->getTopicId()]=$oTopicVote;
$this->Cache_Set($oTopicVote, "topic_question_vote_{$oTopicVote->getTopicId()}_{$oTopicVote->getVoterId()}", array(), 60*60*24*4);
}
}
return $aTopicsQuestionVote;
} }
/** /**
* Добавляет факт голосования за топик-вопрос * Добавляет факт голосования за топик-вопрос
@ -766,5 +979,7 @@ class LsTopic extends Module {
public function GetTopicUnique($sUserId,$sHash) { public function GetTopicUnique($sUserId,$sHash) {
return $this->GetTopicsAdditionalData($this->oMapperTopic->GetTopicUnique($sUserId,$sHash)); return $this->GetTopicsAdditionalData($this->oMapperTopic->GetTopicUnique($sUserId,$sHash));
} }
} }
?> ?>

View file

@ -97,38 +97,25 @@ class TopicEntity_Topic extends Entity
return $this->_aData['topic_text_hash']; return $this->_aData['topic_text_hash'];
} }
public function getCountCommentNew() {
return $this->_aData['count_comment_new'];
}
public function getTagsArray() { public function getTagsArray() {
return explode(',',$this->getTags()); return explode(',',$this->getTags());
} }
public function getUserLogin() { public function getCountCommentNew() {
return $this->_aData['user_login']; return $this->_aData['count_comment_new'];
}
public function getUser() {
return $this->_aData['user'];
} }
public function getBlogType() { public function getBlog() {
return $this->_aData['blog_type']; return $this->_aData['blog'];
}
public function getBlogUrl() {
return $this->_aData['blog_url'];
}
public function getBlogTitle() {
return $this->_aData['blog_title'];
} }
public function getBlogUrlFull() {
if ($this->getBlogType()=='personal') {
return DIR_WEB_ROOT.'/'.ROUTE_PAGE_MY.'/'.$this->getUserLogin().'/';
} else {
return DIR_WEB_ROOT.'/'.ROUTE_PAGE_BLOG.'/'.$this->getBlogUrl().'/';
}
}
public function getUrl() { public function getUrl() {
if ($this->getBlogType()=='personal') { if ($this->getBlog()->getType()=='personal') {
return DIR_WEB_ROOT.'/'.ROUTE_PAGE_BLOG.'/'.$this->getId().'.html'; return DIR_WEB_ROOT.'/'.ROUTE_PAGE_BLOG.'/'.$this->getId().'.html';
} else { } else {
return DIR_WEB_ROOT.'/'.ROUTE_PAGE_BLOG.'/'.$this->getBlogUrl().'/'.$this->getId().'.html'; return DIR_WEB_ROOT.'/'.ROUTE_PAGE_BLOG.'/'.$this->getBlog()->getUrl().'/'.$this->getId().'.html';
} }
} }
public function getUserIsVote() { public function getUserIsVote() {
@ -139,16 +126,7 @@ class TopicEntity_Topic extends Entity
} }
public function getUserQuestionIsVote() { public function getUserQuestionIsVote() {
return $this->_aData['user_question_is_vote']; return $this->_aData['user_question_is_vote'];
} }
public function getUserIsBlogAdministrator() {
return $this->_aData['user_is_blog_administrator'];
}
public function getUserIsBlogModerator() {
return $this->_aData['user_is_blog_moderator'];
}
public function getBlogOwnerId() {
return $this->_aData['blog_owner_id'];
}
public function getIsFavourite() { public function getIsFavourite() {
return $this->_aData['topic_is_favourite']; return $this->_aData['topic_is_favourite'];
} }
@ -381,5 +359,27 @@ class TopicEntity_Topic extends Entity
public function setTextHash($data) { public function setTextHash($data) {
$this->_aData['topic_text_hash']=$data; $this->_aData['topic_text_hash']=$data;
} }
public function setUser($data) {
$this->_aData['user']=$data;
}
public function setBlog($data) {
$this->_aData['blog']=$data;
}
public function setUserQuestionIsVote($data) {
$this->_aData['user_question_is_vote']=$data;
}
public function setUserIsVote($data) {
$this->_aData['user_is_vote']=$data;
}
public function setUserVoteDelta($data) {
$this->_aData['user_vote_delta']=$data;
}
public function setCountCommentNew($data) {
$this->_aData['count_comment_new']=$data;
}
public function setIsFavourite($data) {
$this->_aData['topic_is_favourite']=$data;
}
} }
?> ?>

View file

@ -141,13 +141,13 @@ class Mapper_Topic extends Mapper {
} }
$sql = "SELECT $sql = "SELECT
t.* t.*,
tc.*
FROM FROM
".DB_TABLE_TOPIC." as t ".DB_TABLE_TOPIC." as t
JOIN ".DB_TABLE_TOPIC_CONTENT." AS tc ON t.topic_id=tc.topic_id
WHERE WHERE
t.topic_id IN(?a) t.topic_id IN(?a)
AND
t.publish = 1
ORDER BY FIELD(t.topic_id,?a) "; ORDER BY FIELD(t.topic_id,?a) ";
$aTopics=array(); $aTopics=array();
if ($aRows=$this->oDb->select($sql,$aArrayId,$aArrayId)) { if ($aRows=$this->oDb->select($sql,$aArrayId,$aArrayId)) {
@ -281,6 +281,29 @@ class Mapper_Topic extends Mapper {
return null; return null;
} }
public function GetTopicsVoteByArray($aArrayId,$sUserId) {
if (!is_array($aArrayId) or count($aArrayId)==0) {
return array();
}
$sql = "SELECT
v.*
FROM
".DB_TABLE_TOPIC_VOTE." as v
WHERE
v.user_voter_id = ?d
AND
v.topic_id IN(?a)
";
$aVotes=array();
if ($aRows=$this->oDb->select($sql,$sUserId,$aArrayId)) {
foreach ($aRows as $aRow) {
$aVotes[]=new TopicEntity_TopicVote($aRow);
}
}
return $aVotes;
}
public function increaseTopicCountComment($sTopicId) { public function increaseTopicCountComment($sTopicId) {
$sql = "UPDATE ".DB_TABLE_TOPIC." $sql = "UPDATE ".DB_TABLE_TOPIC."
SET SET
@ -419,6 +442,28 @@ class Mapper_Topic extends Mapper {
return null; return null;
} }
public function GetFavouriteTopicsByArray($aArrayId,$sUserId) {
if (!is_array($aArrayId) or count($aArrayId)==0) {
return array();
}
$sql = "SELECT
f.*
FROM
".DB_TABLE_FAVOURITE_TOPIC." as f
WHERE
f.user_id = ?d
AND
f.topic_id IN(?a)
";
$aFavourites=array();
if ($aRows=$this->oDb->select($sql,$sUserId,$aArrayId)) {
foreach ($aRows as $aRow) {
$aFavourites[]=new TopicEntity_FavouriteTopic($aRow);
}
}
return $aFavourites;
}
public function GetTopicsFavouriteByUserId($sUserId,&$iCount,$iCurrPage,$iPerPage) { public function GetTopicsFavouriteByUserId($sUserId,&$iCount,$iCurrPage,$iPerPage) {
$sql = " $sql = "
SELECT SELECT
@ -521,6 +566,29 @@ class Mapper_Topic extends Mapper {
return false; return false;
} }
public function GetTopicsReadByArray($aArrayId,$sUserId) {
if (!is_array($aArrayId) or count($aArrayId)==0) {
return array();
}
$sql = "SELECT
t.*
FROM
".DB_TABLE_TOPIC_READ." as t
WHERE
t.user_id = ?d
AND
t.topic_id IN(?a)
";
$aReads=array();
if ($aRows=$this->oDb->select($sql,$sUserId,$aArrayId)) {
foreach ($aRows as $aRow) {
$aReads[]=new TopicEntity_TopicRead($aRow);
}
}
return $aReads;
}
public function AddTopicQuestionVote(TopicEntity_TopicQuestionVote $oTopicQuestionVote) { public function AddTopicQuestionVote(TopicEntity_TopicQuestionVote $oTopicQuestionVote) {
$sql = "INSERT INTO ".DB_TABLE_TOPIC_QUESTION_VOTE." $sql = "INSERT INTO ".DB_TABLE_TOPIC_QUESTION_VOTE."
(topic_id, (topic_id,
@ -543,5 +611,28 @@ class Mapper_Topic extends Mapper {
} }
return null; return null;
} }
public function GetTopicsQuestionVoteByArray($aArrayId,$sUserId) {
if (!is_array($aArrayId) or count($aArrayId)==0) {
return array();
}
$sql = "SELECT
v.*
FROM
".DB_TABLE_TOPIC_QUESTION_VOTE." as v
WHERE
v.user_voter_id = ?d
AND
v.topic_id IN(?a)
";
$aVotes=array();
if ($aRows=$this->oDb->select($sql,$sUserId,$aArrayId)) {
foreach ($aRows as $aRow) {
$aVotes[]=new TopicEntity_TopicQuestionVote($aRow);
}
}
return $aVotes;
}
} }
?> ?>

View file

@ -76,6 +76,7 @@ class LsUser extends Module {
if (!is_array($aUserId)) { if (!is_array($aUserId)) {
$aUserId=array($aUserId); $aUserId=array($aUserId);
} }
$aUserId=array_unique($aUserId);
$aUsers=array(); $aUsers=array();
/** /**
* Делаем мульти-запрос к кешу * Делаем мульти-запрос к кешу
@ -139,7 +140,12 @@ class LsUser extends Module {
* @return unknown * @return unknown
*/ */
public function GetUserByActivateKey($sKey) { public function GetUserByActivateKey($sKey) {
return $this->oMapper->GetUserByActivateKey($sKey); $id=$this->oMapper->GetUserByActivateKey($sKey);
$data=$this->GetUsersAdditionalData($id);
if ($id and isset($data[$id])) {
return $data[$id];
}
return null;
} }
/** /**
* Получить юзера по ключу сессии * Получить юзера по ключу сессии
@ -148,7 +154,12 @@ class LsUser extends Module {
* @return unknown * @return unknown
*/ */
public function GetUserByKey($sKey) { public function GetUserByKey($sKey) {
return $this->oMapper->GetUserByKey($sKey); $id=$this->oMapper->GetUserByKey($sKey);
$data=$this->GetUsersAdditionalData($id);
if ($id and isset($data[$id])) {
return $data[$id];
}
return null;
} }
/** /**
* Получить юзера по мылу * Получить юзера по мылу
@ -157,7 +168,12 @@ class LsUser extends Module {
* @return unknown * @return unknown
*/ */
public function GetUserByMail($sMail) { public function GetUserByMail($sMail) {
return $this->oMapper->GetUserByMail($sMail); $id=$this->oMapper->GetUserByMail($sMail);
$data=$this->GetUsersAdditionalData($id);
if ($id and isset($data[$id])) {
return $data[$id];
}
return null;
} }
/** /**
* Получить юзера по логину * Получить юзера по логину
@ -165,17 +181,19 @@ class LsUser extends Module {
* @param unknown_type $sLogin * @param unknown_type $sLogin
* @return unknown * @return unknown
*/ */
public function GetUserByLogin($sLogin) { public function GetUserByLogin($sLogin) {
$s=strtolower($sLogin); $s=strtolower($sLogin);
$s2=-1; if (false === ($data = $this->Cache_Get("user_login_{$s}"))) {
if ($this->oUserCurrent) { if ($id = $this->oMapper->GetUserByLogin($sLogin)) {
$s2=$this->oUserCurrent->getId(); $this->Cache_Set($id, "user_login_{$s}", array(), 60*60*24*1);
}
if (false === ($data = $this->Cache_Get("user_login_{$s}_{$s2}"))) {
if ($data = $this->oMapper->GetUserByLogin($sLogin)) {
$this->Cache_Set($data, "user_login_{$s}_{$s2}", array("user_update_{$data->getId()}","frend_change_frend_{$data->getId()}"), 60*5);
} }
} }
if ($id) {
$data=$this->GetUsersAdditionalData($id);
if (isset($data[$id])) {
return $data[$id];
}
}
return $data; return $data;
} }
/** /**
@ -184,12 +202,12 @@ class LsUser extends Module {
* @param unknown_type $sId * @param unknown_type $sId
* @return unknown * @return unknown
*/ */
public function GetUserById($sId) { public function GetUserById($sId) {
if (false === ($data = $this->Cache_Get("user_{$sId}"))) { $aUsers=$this->GetUsersAdditionalData($sId);
$data = $this->oMapper->GetUserById($sId); if (isset($aUsers[$sId])) {
$this->Cache_Set($data, "user_{$sId}", array("user_update_{$sId}"), 60*5); return $aUsers[$sId];
} }
return $data; return null;
} }
/** /**
* Обновляет юзера * Обновляет юзера

View file

@ -111,97 +111,74 @@ class Mapper_User extends Mapper {
return false; return false;
} }
public function GetUsersByArrayId($aArrayId) {
if (!is_array($aArrayId) or count($aArrayId)==0) {
return array();
}
$sql = "SELECT
u.* ,
IF(ua.user_id IS NULL,0,1) as user_is_administrator
FROM
".DB_TABLE_USER." as u
LEFT JOIN ".DB_TABLE_USER_ADMINISTRATOR." AS ua ON u.user_id=ua.user_id
WHERE
u.user_id IN(?a)
ORDER BY FIELD(u.user_id,?a) ";
$aUsers=array();
if ($aRows=$this->oDb->select($sql,$aArrayId,$aArrayId)) {
foreach ($aRows as $aUser) {
$aUsers[]=new UserEntity_User($aUser);
}
}
return $aUsers;
}
public function GetUserByActivateKey($sKey) { public function GetUserByActivateKey($sKey) {
$sql = "SELECT $sql = "SELECT
u.*, u.user_id
IF(ua.user_id IS NULL,0,1) as user_is_administrator
FROM FROM
".DB_TABLE_USER." as u ".DB_TABLE_USER." as u
LEFT JOIN ".DB_TABLE_USER_ADMINISTRATOR." AS ua ON u.user_id=ua.user_id
WHERE u.user_activate_key = ? "; WHERE u.user_activate_key = ? ";
if ($aRow=$this->oDb->selectRow($sql,$sKey)) { if ($aRow=$this->oDb->selectRow($sql,$sKey)) {
return new UserEntity_User($aRow); return $aRow['user_id'];
} }
return null; return null;
} }
public function GetUserByKey($sKey) { public function GetUserByKey($sKey) {
$sql = "SELECT $sql = "SELECT
u.*, u.user_id
IF(ua.user_id IS NULL,0,1) as user_is_administrator
FROM FROM
".DB_TABLE_USER." as u ".DB_TABLE_USER." as u
LEFT JOIN ".DB_TABLE_USER_ADMINISTRATOR." AS ua ON u.user_id=ua.user_id
WHERE u.user_key = ? "; WHERE u.user_key = ? ";
if ($aRow=$this->oDb->selectRow($sql,$sKey)) { if ($aRow=$this->oDb->selectRow($sql,$sKey)) {
return new UserEntity_User($aRow); return $aRow['user_id'];
}
return null;
}
public function GetUserById($sKey) {
$sql = "SELECT
u.*,
IF(ua.user_id IS NULL,0,1) as user_is_administrator
FROM
".DB_TABLE_USER." as u
LEFT JOIN ".DB_TABLE_USER_ADMINISTRATOR." AS ua ON u.user_id=ua.user_id
WHERE
u.user_id = ? ";
if ($aRow=$this->oDb->selectRow($sql,$sKey)) {
return new UserEntity_User($aRow);
} }
return null; return null;
} }
public function GetUserByMail($sMail) { public function GetUserByMail($sMail) {
$sql = "SELECT $sql = "SELECT
u.*, u.user_id
IF(ua.user_id IS NULL,0,1) as user_is_administrator
FROM FROM
".DB_TABLE_USER." as u ".DB_TABLE_USER." as u
LEFT JOIN ".DB_TABLE_USER_ADMINISTRATOR." AS ua ON u.user_id=ua.user_id
WHERE u.user_mail = ? "; WHERE u.user_mail = ? ";
if ($aRow=$this->oDb->selectRow($sql,strtolower($sMail))) { if ($aRow=$this->oDb->selectRow($sql,$sMail)) {
return new UserEntity_User($aRow); return $aRow['user_id'];
} }
return null; return null;
} }
public function GetUserByLogin($sLogin) { public function GetUserByLogin($sLogin) {
$iCurrentUserId=-1;
if (is_object($this->oUserCurrent)) {
$iCurrentUserId=$this->oUserCurrent->getId();
}
$sql = "SELECT $sql = "SELECT
u.*, u.user_id
IF(uv.user_id IS NULL,0,1) as user_is_vote,
uv.vote_delta as user_vote_delta,
IF(uf.user_id IS NULL,0,1) as user_is_frend
FROM FROM
".DB_TABLE_USER." as u ".DB_TABLE_USER." as u
LEFT JOIN (
SELECT
user_id,
vote_delta
FROM ".DB_TABLE_USER_VOTE."
WHERE user_voter_id = ?d
) AS uv ON uv.user_id = u.user_id
LEFT JOIN (
SELECT
user_id,
user_frend_id
FROM ".DB_TABLE_FRIEND."
WHERE user_id = ?d
) AS uf ON uf.user_frend_id = u.user_id
WHERE WHERE
u.user_login = ? "; u.user_login = ? ";
if ($aRow=$this->oDb->selectRow($sql,$iCurrentUserId,$iCurrentUserId,strtolower($sLogin))) { if ($aRow=$this->oDb->selectRow($sql,$sLogin)) {
return new UserEntity_User($aRow); return $aRow['user_id'];
} }
return null; return null;
} }

View file

@ -1,5 +1,7 @@
{if count($aTopics)>0} {if count($aTopics)>0}
{foreach from=$aTopics item=oTopic} {foreach from=$aTopics item=oTopic}
{assign var="oBlog" value=$oTopic->getBlog()}
{assign var="oUser" value=$oTopic->getUser()}
<!-- Topic --> <!-- Topic -->
<div class="topic"> <div class="topic">
@ -15,11 +17,11 @@
{/if} {/if}
</h1> </h1>
<ul class="action"> <ul class="action">
<li><a href="{$oTopic->getBlogUrlFull()}">{$oTopic->getBlogTitle()|escape:'html'}</a>&nbsp;&nbsp;</li> <li><a href="{$oBlog->getUrlFull()}">{$oBlog->getTitle()|escape:'html'}</a>&nbsp;&nbsp;</li>
{if $oUserCurrent and ($oUserCurrent->getId()==$oTopic->getUserId() or $oUserCurrent->isAdministrator() or $oTopic->getUserIsBlogAdministrator() or $oTopic->getUserIsBlogModerator() or $oTopic->getBlogOwnerId()==$oUserCurrent->getId())} {if $oUserCurrent and ($oUserCurrent->getId()==$oTopic->getUserId() or $oUserCurrent->isAdministrator() or $oBlog->getUserIsAdministrator() or $oBlog->getUserIsModerator() or $oBlog->getOwnerId()==$oUserCurrent->getId())}
<li class="edit"><a href="{$DIR_WEB_ROOT}/{$oTopic->getType()}/edit/{$oTopic->getId()}/" title="{$aLang.topic_edit}">{$aLang.topic_edit}</a></li> <li class="edit"><a href="{$DIR_WEB_ROOT}/{$oTopic->getType()}/edit/{$oTopic->getId()}/" title="{$aLang.topic_edit}">{$aLang.topic_edit}</a></li>
{/if} {/if}
{if $oUserCurrent and ($oUserCurrent->isAdministrator() or $oTopic->getUserIsBlogAdministrator() or $oTopic->getBlogOwnerId()==$oUserCurrent->getId())} {if $oUserCurrent and ($oUserCurrent->isAdministrator() or $oBlog->getUserIsAdministrator() or $oBlog->getOwnerId()==$oUserCurrent->getId())}
<li class="delete"><a href="{$DIR_WEB_ROOT}/{$ROUTE_PAGE_TOPIC}/delete/{$oTopic->getId()}/" title="{$aLang.topic_delete}" onclick="return confirm('{$aLang.topic_delete_confirm}');">{$aLang.topic_delete}</a></li> <li class="delete"><a href="{$DIR_WEB_ROOT}/{$ROUTE_PAGE_TOPIC}/delete/{$oTopic->getId()}/" title="{$aLang.topic_delete}" onclick="return confirm('{$aLang.topic_delete_confirm}');">{$aLang.topic_delete}</a></li>
{/if} {/if}
</ul> </ul>
@ -72,7 +74,7 @@
{if $oTopic->getType()=='link'} {if $oTopic->getType()=='link'}
<li class="link"><a href="{$DIR_WEB_ROOT}/{$ROUTE_PAGE_LINK}/go/{$oTopic->getId()}/" title="{$aLang.topic_link_count_jump}: {$oTopic->getLinkCountJump()}">{$oTopic->getLinkUrl(true)}</a></li> <li class="link"><a href="{$DIR_WEB_ROOT}/{$ROUTE_PAGE_LINK}/go/{$oTopic->getId()}/" title="{$aLang.topic_link_count_jump}: {$oTopic->getLinkCountJump()}">{$oTopic->getLinkUrl(true)}</a></li>
{/if} {/if}
<li class="author"><a href="{$DIR_WEB_ROOT}/{$ROUTE_PAGE_PROFILE}/{$oTopic->getUserLogin()}/">{$oTopic->getUserLogin()}</a></li> <li class="author"><a href="{$DIR_WEB_ROOT}/{$ROUTE_PAGE_PROFILE}/{$oUser->getLogin()}/">{$oUser->getLogin()}</a></li>
<li class="comments-total"> <li class="comments-total">
{if $oTopic->getCountComment()>0} {if $oTopic->getCountComment()>0}
<a href="{$oTopic->getUrl()}#comments" title="{$aLang.topic_comment_read}"><span class="red">{$oTopic->getCountComment()}</span>{if $oTopic->getCountCommentNew()}<span class="green">+{$oTopic->getCountCommentNew()}</span>{/if}</a> <a href="{$oTopic->getUrl()}#comments" title="{$aLang.topic_comment_read}"><span class="red">{$oTopic->getCountComment()}</span>{if $oTopic->getCountCommentNew()}<span class="green">+{$oTopic->getCountCommentNew()}</span>{/if}</a>