Вход Регистрация
Файл: 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'], truetrue);
            
$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($file0mb_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_filefalse);

                    
$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'] < $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}'".$where1);

        if (
$is_exists) { $seolink .= '-' $id; }

        return 
$seolink;

    }

}
Онлайн: 0
Реклама