Файл: components/forum/model.php
Строк: 842
<?php
/******************************************************************************/
// //
// InstantCMS v1.10 //
// http://www.instantcms.ru/ //
// //
// written by InstantCMS Team, 2007-2012 //
// produced by InstantSoft, (www.instantsoft.ru) //
// //
// LICENSED BY GNU/GPL v2 //
// //
/******************************************************************************/
if(!defined('VALID_CMS')) { die('ACCESS DENIED'); }
class cms_model_forum{
private $abstract_array = array();
private $last_addpoll_error = false;
public function __construct(){
$this->inDB = cmsDatabase::getInstance();
$this->config = cmsCore::getInstance()->loadComponentConfig('forum');
cmsCore::loadLanguage('components/forum');
}
////////////////////////////////////////////////////////////////////////////////
public static function getDefaultConfig() {
$cfg = array (
'is_rss' => 1,
'pp_thread' => 15,
'pp_forum' => 15,
'showimg' => 1,
'img_on' => 1,
'img_max' => 5,
'fast_on' => 1,
'fast_bb' => 1,
'fa_on' => 1,
'group_access' => '',
'fa_max' => 25,
'fa_ext' => 'txt doc zip rar arj png gif jpg jpeg bmp',
'fa_size' => 1024,
'edit_minutes' => 0,
'watermark' => 0,
'ranks' => array(),
'modrank' => 0
);
return $cfg;
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
public function isForumModerator($moder_list){
if(cmsUser::isUserCan('forum/moderate')) { return true; }
if (!$moder_list) { return false; }
$moder_list = cmsCore::yamlToArray($moder_list);
if (!is_array($moder_list)) { return false; }
return in_array(cmsUser::getInstance()->id, $moder_list);
}
public function getForumModerators($moder_list){
if (!$moder_list) { return array(); }
$moder_list = cmsCore::yamlToArray($moder_list);
if (!is_array($moder_list)) { return array(); }
$ids_list = rtrim(implode(',', $moder_list), ',');
return $this->inDB->get_table('cms_users', "id IN ({$ids_list})", 'id, login, nickname');
}
////////////////////////////////////////////////////////////////////////////////
////////////// методы для кеширования статистических даных /////////////////////
////////////////////////////////////////////////////////////////////////////////
/**
* Кеширует количество постов тем форума
* в таблицу cms_forums
* @param int $forum_left_key
* @param int $forum_right_key
* @return bool
*/
public function updateForumPostsCount($forum_left_key, $forum_right_key) {
$sql = "SELECT IFNULL(SUM(t.post_count), 0) AS post_count
FROM cms_forum_threads t
INNER JOIN cms_forums f ON f.id = t.forum_id AND f.NSLeft >= '$forum_left_key' AND f.NSRight <= '$forum_right_key' AND f.published = 1";
$result = $this->inDB->query($sql);
$post = $this->inDB->fetch_assoc($result);
return $this->inDB->query("UPDATE cms_forums SET post_count = '{$post['post_count']}' WHERE NSLeft = '$forum_left_key' AND NSRight = '$forum_right_key' LIMIT 1");
}
/**
* Кеширует количество постов темы
* в таблицу cms_forum_threads
* @param int $thread_id
* @return bool
*/
public function updateThreadPostCount($thread_id) {
$sql = "SELECT p.id
FROM cms_forum_posts p
INNER JOIN cms_forum_threads t ON t.id = '{$thread_id}' AND t.id = p.thread_id";
$result = $this->inDB->query($sql);
$post_count = $this->inDB->num_rows($result);
$this->inDB->query("UPDATE cms_forum_threads SET post_count = '{$post_count}' WHERE id = '{$thread_id}' LIMIT 1");
return $post_count;
}
/**
* Кеширует последний пост в теме
* в таблицу cms_forum_threads
* @param int $thread_id
* @return bool
*/
public function cacheThreadLastPost($thread_id) {
$sql = "SELECT p.pubdate, p.id, p.content_html,
u.nickname as author_nickname,
u.login as author_login,
t.title as thread_title, t.id as thread_id, t.post_count
FROM cms_forum_posts p
INNER JOIN cms_forum_threads t ON t.id = p.thread_id AND t.id = '{$thread_id}'
LEFT JOIN cms_users u ON u.id = p.user_id
ORDER BY p.pubdate DESC
LIMIT 1";
$result = $this->inDB->query($sql);
if (!$this->inDB->num_rows($result)){ return true; }
$post = $this->formLastPostArray($this->inDB->fetch_assoc($result));
$yaml_post = $this->inDB->escape_string(cmsCore::arrayToYaml($post));
return $this->inDB->query("UPDATE cms_forum_threads SET last_msg = '{$yaml_post}', pubdate = '{$post['pubdate']}' WHERE id = '{$post['thread_id']}' LIMIT 1");
}
/**
* Кеширует количество тем форума
* в таблицу cms_forums
* @param int $forum_left_key
* @param int $forum_right_key
* @return bool
*/
public function updateForumThreadsCount($forum_left_key, $forum_right_key) {
$sql = "SELECT t.id
FROM cms_forum_threads t
INNER JOIN cms_forums f ON f.id = t.forum_id AND f.NSLeft >= '$forum_left_key' AND f.NSRight <= '$forum_right_key' AND f.published = 1";
$result = $this->inDB->query($sql);
$thread_count = $this->inDB->num_rows($result);
return $this->inDB->query("UPDATE cms_forums SET thread_count = '{$thread_count}' WHERE NSLeft = '$forum_left_key' AND NSRight = '$forum_right_key' LIMIT 1");
}
/**
* Кеширует массив последнего сообщения темы форума
* в таблицу cms_forums и cms_forum_threads
* @param int $forum_left_key
* @param int $forum_right_key
* @return bool
*/
public function cacheLastPost($forum_left_key, $forum_right_key) {
$post = $this->getForumLastPost($forum_left_key, $forum_right_key);
$yaml_post = $this->inDB->escape_string(cmsCore::arrayToYaml($post));
$this->inDB->query("UPDATE cms_forums SET last_msg = '{$yaml_post}' WHERE NSLeft = '$forum_left_key' AND NSRight = '$forum_right_key' LIMIT 1");
if(isset($post['thread_id'])){
$this->inDB->query("UPDATE cms_forum_threads SET last_msg = '{$yaml_post}', pubdate = '{$post['pubdate']}' WHERE id = '{$post['thread_id']}' LIMIT 1");
}
return true;
}
/**
* Кеширует данные форума
* используя методы выше
* @param int $forum_left_key
* @param int $forum_right_key
* @param bool $and_parent Метка обновления текущего форума и выше него
* @return bool
*/
public function updateForumCache($forum_left_key, $forum_right_key, $and_parent = false) {
if(!$and_parent){
$this->updateForumPostsCount($forum_left_key, $forum_right_key);
$this->updateForumThreadsCount($forum_left_key, $forum_right_key);
$this->cacheLastPost($forum_left_key, $forum_right_key);
return true;
}
$path_list = $this->inDB->getNsCategoryPath('cms_forums', $forum_left_key, $forum_right_key, 'NSLeft, NSRight');
if ($path_list){
$path_list = array_reverse($path_list);
foreach($path_list as $pcat){
$this->updateForumCache($pcat['NSLeft'], $pcat['NSRight']);
}
}
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/**
* Возвращает тему форума
* @param int $id ID темы
* @return array
*/
public function getThread($id){
$thread = $this->inDB->get_fields('cms_forum_threads t
INNER JOIN cms_forums f ON f.id = t.forum_id',
"t.id = '$id'",
't.*, f.NSLeft, f.NSRight');
if(!$thread){ return false; }
$thread['fpubdate'] = cmsCore::dateFormat($thread['pubdate']);
$thread['is_mythread'] = $thread['user_id'] == cmsUser::getInstance()->id;
return cmsCore::callEvent('GET_FORUM_THREAD', $thread);
}
////////////////////////////////////////////////////////////////////////////////
/**
* Возвращает категорию форума
* @param mixed $id
* @return array
*/
public function getForumCat($id){
if(is_numeric($id)){
$where = "id = '$id'";
} else {
$where = "seolink = '$id'";
}
$cat = $this->inDB->get_fields('cms_forum_cats', $where, '*');
if(!$cat){ return false; }
return cmsCore::callEvent('GET_FORUM_CAT', $cat);
}
////////////////////////////////////////////////////////////////////////////////
/**
* Возвращает форум
* @param int $id ID форума
* @return array
*/
public function getForum($id){
$forum = $this->inDB->get_fields('cms_forums', "id = '$id'", '*');
if(!$forum){ return false; }
$forum['last_msg_array'] = cmsCore::yamlToArray($forum['last_msg']);
if($forum['last_msg_array']){
$forum['last_msg_array']['fpubdate'] = cmsCore::dateFormat($forum['last_msg_array']['pubdate']);
}
return cmsCore::callEvent('GET_FORUM', $forum);
}
////////////////////////////////////////////////////////////////////////////////
/**
* Возвращает пост темы
* @param int $id
* @return array
*/
public function getPost($id){
$post = $this->inDB->get_fields('cms_forum_posts', "id = '$id'", '*');
if(!$post){ return false; }
return cmsCore::callEvent('GET_FORUM_POST', $post);
}
////////////////////////////////////////////////////////////////////////////////
/**
* Возвращает последний пост форума
* @param int $forum_left_key
* @param int $forum_right_key
* @return array
*/
public function getForumLastPost($left_key, $right_key){
$sql = "SELECT p.pubdate, p.id, p.content_html,
u.nickname as author_nickname,
u.login as author_login,
t.title as thread_title, t.id as thread_id, t.post_count
FROM cms_forum_posts p
INNER JOIN cms_forum_threads t ON t.id = p.thread_id
INNER JOIN cms_forums f ON f.id = t.forum_id AND f.NSLeft >= '{$left_key}' AND f.NSRight <= '{$right_key}'
LEFT JOIN cms_users u ON u.id = p.user_id
ORDER BY p.pubdate DESC
LIMIT 1";
$result = $this->inDB->query($sql) ;
if (!$this->inDB->num_rows($result)){ return array(); }
return $this->formLastPostArray($this->inDB->fetch_assoc($result));
}
private function formLastPostArray($post) {
$post['lastpage'] = ceil($post['post_count'] / $this->config['pp_thread']);
$link = '/forum/thread'.$post['thread_id'].'-'.$post['lastpage'].'.html#'.$post['id'];
$post['thread_link'] = '<a href="'.$link.'">'.$post['thread_title'].'</a>';
$post['user_link'] = cmsUser::getProfileLink($post['author_login'], $post['author_nickname']);
return $post;
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
public function whereForumCatIs($cat_id) {
$this->inDB->where("f.category_id = '{$cat_id}'");
}
public function whereNestedForum($left_key, $right_key) {
$this->inDB->where("f.NSLeft > '{$left_key}' AND f.NSRight < '{$right_key}'");
}
public function whereThisAndNestedForum($left_key, $right_key) {
$this->inDB->where("f.NSLeft >= '{$left_key}' AND f.NSRight <= '{$right_key}'");
}
public function getForums($is_admin=false){
$pub_sql = $is_admin ? '' : ' AND f.published = 1';
$sql = "SELECT f.*, cat.title as cat_title, cat.seolink as cat_seolink
FROM cms_forums f
LEFT JOIN cms_forum_cats cat ON cat.id = f.category_id AND cat.published = 1
WHERE f.parent_id > 0 {$pub_sql}
{$this->inDB->where}
ORDER BY cat.ordering, f.NSLeft n";
if ($this->inDB->limit){
$sql .= "LIMIT {$this->inDB->limit}";
}
$result = $this->inDB->query($sql);
$this->inDB->resetConditions();
if(!$this->inDB->num_rows($result)){ return array(); }
while ($forum = $this->inDB->fetch_assoc($result)){
// Уровень первого элемента
$first_level = isset($first_level) ? $first_level : $forum['NSLevel'];
// проверяем доступ к форуму
if(!cmsCore::checkContentAccess($forum['access_list'])) { continue; }
// получаем массив последнего сообщения
$forum['last_msg_array'] = cmsCore::yamlToArray($forum['last_msg']);
if($forum['last_msg_array']){
$forum['last_msg_array']['fpubdate'] = cmsCore::dateFormat($forum['last_msg_array']['pubdate']);
}
// Путь до иконки форума
$forum['icon_url'] = '/upload/forum/cat_icons/'.($forum['icon'] ? $forum['icon'] : 'forum.gif');
// Формируем корневой уровень
if($forum['NSLevel'] == $first_level){
$forums[] = $forum;
} else { // формируем подфорумы
$forums[end(array_keys($forums))]['sub_forums'][] = $forum;
}
}
return cmsCore::callEvent('GET_FORUMS', $forums);
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
public function whereDayIntervalIs($day) {
$this->inDB->where("DATEDIFF(NOW(), t.pubdate) <= {$day}");
}
public function whereForumIs($forum_id) {
$this->inDB->where("t.forum_id = '{$forum_id}'");
}
public function whereThreadUserIs($user_id) {
$this->inDB->where("t.user_id = '{$user_id}'");
}
public function wherePublicThreads() {
$this->inDB->where("t.is_hidden = 0");
}
public function wherePinnedThreads() {
$this->inDB->where("t.pinned = 1");
}
public function getThreads(){
$sql = "SELECT t.*, u.nickname, u.login {$this->inDB->select}
FROM cms_forum_threads t
LEFT JOIN cms_users u ON u.id = t.user_id
{$this->inDB->join}
WHERE 1=1
{$this->inDB->where}
{$this->inDB->group_by}
{$this->inDB->order_by} n";
if ($this->inDB->limit){
$sql .= "LIMIT {$this->inDB->limit}";
}
$result = $this->inDB->query($sql);
$this->inDB->resetConditions();
if(!$this->inDB->num_rows($result)){ return array(); }
while ($thread = $this->inDB->fetch_assoc($result)){
$thread['last_msg_array'] = cmsCore::yamlToArray($thread['last_msg']);
if($thread['last_msg_array']){
$thread['last_msg_array']['fpubdate'] = cmsCore::dateFormat($thread['last_msg_array']['pubdate']);
}
$thread['fpubdate'] = cmsCore::dateFormat($thread['pubdate']);
$thread['is_new'] = (bool)(strtotime($thread['pubdate']) > strtotime(cmsUser::getInstance()->logdate));
$thread['answers'] = $thread['post_count']-1;
$thread['pages'] = ceil($thread['post_count'] / $this->config['pp_thread']);
$threads[] = $thread;
}
return cmsCore::callEvent('GET_THREADS', $threads);
}
public function getThreadsCount() {
$sql = "SELECT 1
FROM cms_forum_threads t
WHERE 1=1
{$this->inDB->where}
{$this->inDB->group_by}n";
$result = $this->inDB->query($sql);
return $this->inDB->num_rows($result);
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
public function whereThreadIs($thread_id) {
$this->inDB->where("p.thread_id = '{$thread_id}'");
}
public function wherePostUserIs($user_id) {
$this->inDB->where("p.user_id = '{$user_id}'");
}
public function getPosts(){
$inUser = cmsUser::getInstance();
$sql = "SELECT p.id, p.thread_id, p.user_id, p.pubdate, p.editdate, p.edittimes, p.rating, p.attach_count, p.content_html, p.pinned,
u.nickname, u.login, u.is_deleted, u.logdate, u.status,
up.imageurl, up.signature_html, up.city, up.karma, g.access as group_access, g.is_admin {$this->inDB->select}
FROM cms_forum_posts p
{$this->inDB->join}
LEFT JOIN cms_users u ON u.id = p.user_id
LEFT JOIN cms_user_profiles up ON up.user_id = u.id
LEFT JOIN cms_user_groups g ON u.group_id = g.id
WHERE 1=1
{$this->inDB->where}
{$this->inDB->group_by}
{$this->inDB->order_by} n";
if ($this->inDB->limit){
$sql .= "LIMIT {$this->inDB->limit}";
}
$result = $this->inDB->query($sql);
$this->inDB->resetConditions();
if(!$this->inDB->num_rows($result)){ return array(); }
while ($post = $this->inDB->fetch_assoc($result)){
$post['fpubdate'] = cmsCore::dateFormat($post['pubdate']);
$post['wday'] = cmsCore::dateToWday($post['pubdate']);
$post['peditdate'] = cmsCore::dateFormat($post['editdate'], true, true);
$post['post_count'] = $this->getUserPostsCount($post['user_id']);
$post['avatar_url'] = cmsUser::getUserAvatarUrl($post['user_id'], 'small', $post['imageurl'], $post['is_deleted']);
$post['flogdate'] = cmsUser::getOnlineStatus($post['user_id'], $post['logdate']);
$post['userrank'] = $this->getForumUserRank($post);
$post['user_awards'] = cmsUser::getAwardsList($post['user_id']);
$post['attached_files'] = $this->config['fa_on'] && $post['attach_count'] ?
$this->getPostAttachments($post['id']) : array();
$end_min = $this->checkEditTime($post['pubdate']);
$post['is_author'] = ($post['user_id'] == cmsUser::getInstance()->id);
$post['is_author_can_edit'] = (is_bool($end_min) ? $end_min : $end_min > 0) && $post['is_author'];
if ($inUser->id){
$post['is_voted'] = $post['is_author'] ? true : cmsUser::isRateUser('forum_post', $inUser->id, $post['id']);
} else {
$post['is_voted'] = true;
}
$posts[] = $post;
}
$this->resetAbstractArray();
return cmsCore::callEvent('GET_FORUM_POSTS', $posts);
}
public function getPostsCount() {
$sql = "SELECT 1
FROM cms_forum_posts p
{$this->inDB->join}
WHERE 1=1
{$this->inDB->where}
{$this->inDB->group_by}n";
$result = $this->inDB->query($sql);
return $this->inDB->num_rows($result);
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
public function resetAbstractArray($array_param=0){
if(!$array_param){
$this->abstract_array = array();
} else {
$this->abstract_array[$array_param] = array();
}
}
public function getUserPostsCount($user_id){
if(!isset($this->abstract_array['users_post_count'][$user_id])){
$this->abstract_array['users_post_count'][$user_id] = $this->inDB->rows_count('cms_forum_posts', "user_id = '$user_id'");
}
return $this->abstract_array['users_post_count'][$user_id];
}
public function getForumUserRank($post){
global $_LANG;
// Значения по умолчанию
$output = array('group'=>'','rank'=>$_LANG['USER'], 'class'=>'user_rank');
// Получаем звания
if(is_array($this->config['ranks'])){
foreach($this->config['ranks'] as $rank){
if ($post['post_count'] >= $rank['msg'] && $rank['msg']){
$user_rank = $rank['title'];
}
}
}
// Звания для админов
if($post['is_admin']){
$output['class'] = 'admin_rank';
$output['group'] = $_LANG['ADMINISTRATOR'];
$output['rank'] = $this->config['modrank'] && isset($user_rank) ? $user_rank : '';
return $output;
}
// Звания для модераторов
if (mb_strstr($post['group_access'], 'forum/moderate')){
$output['group'] = $_LANG['MODER'];
$output['rank'] = $this->config['modrank'] && isset($user_rank) ? $user_rank : '';
$output['class'] = 'moder_rank';
return $output;
}
// Для остальных пользователей
$output['rank'] = @$user_rank ? $user_rank : $output['rank'];
return $output;
}
public function checkEditTime($pubdate) {
if($this->config['edit_minutes'] == 0) { return true; }
if($this->config['edit_minutes'] == -1) { return false; }
return $this->config['edit_minutes'] - round((time() - strtotime($pubdate))/60);
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
public function addPost($post){
// Получаем последний пост темы
$last_post = $this->inDB->get_fields('cms_forum_posts', "thread_id = '{$post['thread_id']}'", '*', 'pubdate DESC');
// Если он этого же автора и прошло не более 20 минут, склеиваем, иначе просто добавляем
$minutes_passed = round((time() - strtotime($last_post['pubdate']))/60);
if($last_post['user_id'] == $post['user_id'] && $minutes_passed < 20){
global $_LANG;
$u_post['content'] = $this->inDB->escape_string($last_post['content']."rn".$post['content']);
$u_post['content_html'] = $this->inDB->escape_string($last_post['content_html'].'<em class="added_later">'.
$_LANG['ADDED_LATER'].
($minutes_passed ?
cmsCore::spellCount($minutes_passed, $_LANG['MINUTU1'], $_LANG['MINUTE2'], $_LANG['MINUTE10']) :
$_LANG['FEW_SECONDS']).
'</em>'.$post['content_html']);
$this->updatePost($u_post, $last_post['id']);
return $last_post['id'];
}
$post_id = $this->inDB->insert('cms_forum_posts', cmsCore::callEvent('ADD_FORUM_POST', $post));
// регистрируем загруженные изображения
cmsCore::setIdUploadImage('post', $post_id);
return $post_id;
}
public function updatePost($post, $post_id){
cmsCore::callEvent('UPDATE_FORUM_POST', $post_id);
cmsCore::setIdUploadImage('post', $post_id);
return $this->inDB->update('cms_forum_posts', $post, $post_id);
}
public function deletePost($post_id){
cmsCore::callEvent('DELETE_POST', $post_id);
$this->deletePostAttachments($post_id);
cmsCore::deleteUploadImages($post_id, 'post');
$this->inDB->delete('cms_forum_posts', "id = '{$post_id}'", 1);
cmsActions::removeObjectLog('add_fpost', $post_id);
return true;
}
public function isBelongsToPostTopic($post_id, $thread_id){
return $this->inDB->get_field('cms_forum_posts', "id = '$post_id' AND thread_id = '$thread_id'", 'id');
}
public function addThread($thread){
return $this->inDB->insert('cms_forum_threads', cmsCore::callEvent('ADD_THREAD', $thread));
}
public function closeThread($thread_id){
cmsCore::callEvent('CLOSE_THREAD', $thread_id);
global $_LANG;
return $this->inDB->query("UPDATE cms_forum_threads
SET title = CONCAT('{$_LANG['TOPIC_FIXED_PREFIX']} ', title), closed = 1
WHERE id = '$thread_id'");
}
public function openThread($thread_id){
cmsCore::callEvent('OPEN_THREAD', $thread_id);
global $_LANG;
return $this->inDB->query("UPDATE cms_forum_threads
SET title = REPLACE(title, '{$_LANG['TOPIC_FIXED_PREFIX']}', ''), closed = 0
WHERE id = '$thread_id'");
}
public function deleteThread($thread_id){
cmsActions::removeObjectLog('add_thread', $thread_id);
$this->whereThreadIs($thread_id);
$posts = $this->getPosts();
if ($posts){
foreach ($posts as $post) {
$this->deletePost($post['id']);
}
}
$this->inDB->query("DELETE FROM cms_forum_threads WHERE id = '{$thread_id}'");
$poll = $this->getThreadPoll($thread_id);
if($poll){
$this->deletePoll($poll['id']);
}
}
public function updateThread($thread, $thread_id){
cmsCore::callEvent('UPDATE_THREAD', $thread_id);
return $this->inDB->update('cms_forum_threads', $thread, $thread_id);
}
////////////////////////////////////////////////////////////////////////////////
/////////////////////// методы для прикрепленных файлов ////////////////////////
////////////////////////////////////////////////////////////////////////////////
/**
* Загружает и добавляет/обновляет файл(ы)
* @param int $post_id
* @param array $input_file
* @return str имя файла
*/
public function addUpdatePostAttachments($post_id, $input_file=array(), $count_files = 0) {
if(!@$_FILES['fa']['name'][0]) { return 0; }
$success = true;
foreach ($_FILES['fa']['error'] as $key => $error) {
if($count_files > $this->config['fa_max']) { $success = false; break; }
if($_FILES['fa']['size'][$key] > $this->config['fa_size']*1024) { $success = false; continue; }
$file = $_FILES['fa']['name'][$key];
$pp = pathinfo($file);
$ext = mb_strtolower($pp['extension']);
if(in_array($ext, array('php','htm','html','htaccess'))) { $success = false; continue; }
if (!mb_stristr($this->config['fa_ext'], $ext)){ $success = false; continue; }
$file = cmsCore::strToURL(mb_substr($file, 0, mb_strrpos($file, '.'))) . '_' . uniqid() . '.' . $ext;
@mkdir(PATH.'/upload/forum/post'.$post_id);
$destination = PATH.'/upload/forum/post'.$post_id.'/'.$file;
// Формируем массив
$result['filesize'] = $this->inDB->escape_string($_FILES['fa']['size'][$key]);
$result['post_id'] = $post_id;
$result['hits'] = 0;
$result['pubdate'] = date("Y-m-d H:i:s");
$result['filename'] = $this->inDB->escape_string($file);
if (cmsCore::moveUploadedFile($_FILES['fa']['tmp_name'][$key], $destination, $error)) {
if(!$input_file){ //Если новый файл
$this->inDB->insert('cms_forum_files', $result);
} else { // Если обновляем файл
$this->deletePostAttachment($input_file, false);
$this->inDB->update('cms_forum_files', $result, $input_file['id']);
break; // подразумевается, что обновляем 1 файл
}
} else {
$success = false;
@rmdir(PATH.'/upload/forum/post'.$post_id);
}
$count_files++;
}
$this->updatePostAttachmentsCount($post_id);
return $success;
}
/**
* Кеширует кол-во вложений к посту
* @param int $post_id
* @return bool
*/
public function updatePostAttachmentsCount($post_id) {
$post_file_count = $this->inDB->rows_count('cms_forum_files', "post_id = '$post_id'");
return $this->inDB->update('cms_forum_posts', array('attach_count'=>$post_file_count), $post_id);
}
/**
* Удаляет прикрепленные файлы к посту темы
* @param int $post_id
* @return bool
*/
public function deletePostAttachments($post_id) {
$files = $this->getPostAttachments($post_id);
if(!$files) { return false; }
foreach ($files as $file) {
$this->deletePostAttachment($file);
}
return true;
}
/**
* Удаляет файл
* @param array $file
* @return bool
*/
public function deletePostAttachment($file, $whith_db = true) {
cmsCore::callEvent('DELETE_POST_FILE', $file);
@unlink(PATH.'/upload/forum/post'.$file['post_id'].'/'.$file['filename']);
@rmdir(PATH.'/upload/forum/post'.$file['post_id']);
if($whith_db){
$this->inDB->delete('cms_forum_files', "id = '{$file['id']}'", 1);
$this->updatePostAttachmentsCount($file['post_id']);
}
return true;
}
/**
* Получает прикрепленный файл
* @param array $file
* @return bool
*/
public function getPostAttachment($file_id) {
$file = $this->inDB->get_fields('cms_forum_files', "id = '{$file_id}'", '*');
if(!$file){ return false; }
return cmsCore::callEvent('GET_POST_FILE', $file);
}
/**
* Возвращает файлы поста
* @param int $post_id
* @return bool
*/
public function getPostAttachments($post_id){
$sql = "SELECT *
FROM cms_forum_files
WHERE post_id = '$post_id'";
$result = $this->inDB->query($sql) ;
if (!$this->inDB->num_rows($result)){ return array(); }
$img_ext = array('jpg','jpeg','gif','png','bmp');
while($file = $this->inDB->fetch_assoc($result)){
$path_parts = pathinfo($file['filename']);
$ext = $path_parts['extension'];
$file['is_img'] = in_array($ext, $img_ext) && $this->config['showimg'];
$file['icon'] = cmsCore::fileIcon($file['filename']);
$file['filesize_kb'] = round(($file['filesize']/1024),2);
$files[] = $file;
}
return cmsCore::callEvent('GET_POST_FILES', $files);
}
////////////////////////////////////////////////////////////////////////////////
/////////////////////////// методы для опросов /////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/**
* Создает опрос
* @param array $poll
* @param int $thread_id
* @return int
*/
public function addPoll($poll, $thread_id){
global $_LANG;
// если заголовка опроса нет, считаем что опрос не нужен
$t_poll['title'] = cmsCore::strClear($poll['title']);
if(!$t_poll['title']) { return false; }
$t_poll['description'] = cmsCore::strClear($poll['desc']);
$t_poll['enddate'] = date("Y-m-d H:i:s", (((int)$poll['days']*86400) + time()));
$options['result'] = (int)$poll['result'];
$options['change'] = (int)$poll['change'];
$t_poll['options'] = cmsCore::arrayToYaml($options);
$answers = array();
foreach($poll['answers'] as $answer){
if ($answer) {
$answers[strip_tags($answer)] = 0;
}
}
if (sizeof($answers)<2){ $this->last_addpoll_error = $_LANG['ERR_POLL_VARIANT']; return false; }
$t_poll['answers'] = $this->inDB->escape_string(cmsCore::arrayToYaml($answers));
$t_poll['thread_id'] = $thread_id;
return $this->inDB->insert('cms_forum_polls', cmsCore::callEvent('ADD_FORUM_POLL', $t_poll));
}
/**
* Обновляет опрос
* @param array $poll
* @param array $latest_poll
* @return bool
*/
public function updatePoll($poll, $latest_poll){
global $_LANG;
$t_poll['title'] = cmsCore::strClear($poll['title']);
if(!$t_poll['title']) { return false; }
$t_poll['description'] = cmsCore::strClear($poll['desc']);
$t_poll['enddate'] = date("Y-m-d H:i:s", (((int)$poll['days']*86400) + time()));
$options['result'] = (int)$poll['result'];
$options['change'] = (int)$poll['change'];
$t_poll['options'] = cmsCore::arrayToYaml($options);
// Формируем массив голосов
foreach ($latest_poll['answers'] as $vote_count) {
$vote_counts[] = $vote_count;
}
// Новый массив вопросов
foreach($poll['answers'] as $new_answer){
$new_answers[] = strip_tags($new_answer);
}
// Результирующий массив
foreach($new_answers as $key=>$answer){
if($answer) {
$answers[$answer] = isset($vote_counts[$key]) ? $vote_counts[$key] : 0;
}
}
if (sizeof($answers)<2){ $this->last_addpoll_error = $_LANG['ERR_POLL_VARIANT']; return false; }
$t_poll['answers'] = $this->inDB->escape_string(cmsCore::arrayToYaml($answers));
return $this->inDB->update('cms_forum_polls', cmsCore::callEvent('UPDATE_FORUM_POLL', $t_poll), $latest_poll['id']);
}
public function getLastAddPollError() {
return $this->last_addpoll_error;
}
public function getThreadPoll($thread_id) {
return $this->getPoll("thread_id = '{$thread_id}'");
}
public function getPollById($id) {
return $this->getPoll("id = '{$id}'");
}
/**
* Возвращает опрос
* @param str $where условия запроса
* @return int
*/
public function getPoll($where) {
$poll = $this->inDB->get_fields('cms_forum_polls', $where, '*');
if(!$poll){ return false; }
global $_LANG;
$poll['answers'] = cmsCore::yamlToArray($poll['answers']);
$num = 1;
foreach ($poll['answers'] as $key => $value) {
$poll['answers_key'][$num] = $key;
$num++;
}
$poll['options'] = cmsCore::yamlToArray($poll['options']);
switch ($poll['options']['result']) {
case 0:
$poll['options']['result_text'] = $_LANG['AVAILABLE_FOR_ALL'];
break;
case 1:
$poll['options']['result_text'] = $_LANG['AVAILABLE_FOR_VOTERS'];
break;
case 2:
$poll['options']['result_text'] = $_LANG['AVAILABLE_AFTER_VOTE'];
break;
}
switch ($poll['options']['change']) {
case 0:
$poll['options']['change_text'] = $_LANG['PROHIBITED'];
break;
case 1:
$poll['options']['change_text'] = $_LANG['ALLOW'];
break;
}
$poll['days_left'] = round((strtotime($poll['enddate']) - time())/86400);
$poll['days_left'] = $poll['days_left'] < 0 ? 0 : $poll['days_left'];
$poll['is_closed'] = $poll['days_left'] <= 0;
$poll['is_user_vote'] = $this->isUserVoted($poll['id']);
// совместимость старых типов ответов, по id
// если пользователь проголосовал
if(!is_bool($poll['is_user_vote'])){
if(is_numeric($poll['is_user_vote'])){
$poll['is_user_vote'] = $poll['answers_key'][$poll['is_user_vote']];
}
}
$poll['vote_count'] = $this->getVoteCount($poll['answers']);
$poll['fenddate'] = cmsCore::dateFormat($poll['enddate']);
$poll['show_result'] = false;
return cmsCore::callEvent('GET_THREAD_POLL', $poll);
}
public function deletePoll($poll_id){
cmsCore::callEvent('DELETE_FORUM_POLL', $poll_id);
$this->inDB->delete('cms_forum_polls', "id = '$poll_id'", 1);
$this->inDB->delete('cms_forum_votes', "poll_id = '$poll_id'", 1);
return true;
}
private function getVoteCount($poll_answers = array()){
$count = 0;
foreach($poll_answers as $num){
$count += (int)$num;
}
return $count;
}
public function isUserVoted($poll_id){
$inUser = cmsUser::getInstance();
// считаем что гости голосовали
if(!$inUser->id) { return true; }
return $this->inDB->get_field('cms_forum_votes', "user_id='{$inUser->id}' AND poll_id = '$poll_id'", 'answer');
}
public function votePoll($poll, $answer){
if(!$poll['answers']){ return false; }
$inUser = cmsUser::getInstance();
//Прибавляем голос к переданному нам варианту ответа
foreach($poll['answers'] as $key=>$value){
if ($key == $answer){
$poll['answers'][$key] += 1;
}
}
$answers = $this->inDB->escape_string(cmsCore::arrayToYaml($poll['answers']));
//Сохраняем результаты опроса
$sql = "UPDATE cms_forum_polls SET answers = '{$answers}' WHERE id = '{$poll['id']}'";
$this->inDB->query($sql);
// помечаем кто за что проголосовал
$sql = "INSERT cms_forum_votes (poll_id, answer, user_id, pubdate)
VALUES ('{$poll['id']}', '$answer', '{$inUser->id}', NOW())";
$this->inDB->query($sql);
return true;
}
public function deleteVote($poll){
if(!$poll['answers']){ return false; }
$inUser = cmsUser::getInstance();
// Убираем голос пользователя
foreach($poll['answers'] as $key=>$value){
if ($key == $poll['is_user_vote']){
$poll['answers'][$key] -= 1;
}
}
$answers = $this->inDB->escape_string(cmsCore::arrayToYaml($poll['answers']));
$this->inDB->query("UPDATE cms_forum_polls SET answers = '{$answers}' WHERE id = '{$poll['id']}'");
$this->inDB->delete('cms_forum_votes', "poll_id = '{$poll['id']}' AND user_id = '{$inUser->id}'", 1);
return true;
}
public function getCatSeoLink($title = '', $id = 0){
$seolink = cmsCore::strToURL($title);
if ($id){
$where = ' AND id<>'.$id;
} else {
$where = '';
}
$is_exists = $this->inDB->rows_count('cms_forum_cats', "seolink='{$seolink}'".$where, 1);
if ($is_exists) { $seolink .= '-' . $id; }
return $seolink;
}
}