Seditio Source
Root |
./othercms/PHPFusion 9.10.20/infusions/forum/classes/server.php
<?php
/*-------------------------------------------------------+
| PHPFusion Content Management System
| Copyright (C) PHP Fusion Inc
| https://phpfusion.com/
+--------------------------------------------------------+
| Filename: server.php
| Author: Chan (Frederick MC Chan)
+--------------------------------------------------------+
| This program is released as free software under the
| Affero GPL license. You can redistribute it and/or
| modify it under the terms of this license which you
| can read by viewing the included agpl.txt or online
| at www.gnu.org/licenses/agpl.html. Removal of this
| copyright header is strictly prohibited without
| written permission from the original author(s).
+--------------------------------------------------------*/

namespace PHPFusion\Forums;

use
PHPFusion\Forums\Post\NewThread;
use
PHPFusion\Forums\Postify\Forum_Postify;
use
PHPFusion\Forums\Threads\Forum_Mood;
use
PHPFusion\Forums\Threads\ThreadFilter;

abstract class
ForumServer {

   
/**
     * Moderator object
     *
     * @return object
     */
   
public static $moderator_instance = NULL;

   
/* Forum icons */
    /**
     * Thread filter object
     *
     * @return object
     */
   
public static $filter_instance = NULL;
   
/**
     * Forum object
     *
     * @return object
     */
   
public static $forum_instance = NULL;
   
/**
     * Tag object
     *
     * @return object
     */
   
public static $tag_instance = NULL;
   
/**
     * Thread object
     *
     * @return object
     */
   
public static $thread_instance = NULL;
   
/**
     * Post object
     *
     * @var null
     */
   
public static $new_thread_instance = NULL;
   
/**
     * Mood object
     *
     * @return object
     */
   
public static $forum_mood_instance = NULL;

    public static
$postify_instance = NULL;

    protected static
$forum_settings = [];

    protected static
$forum_template_paths = [];

    static private
$forum_icons = [
       
'forum'    => 'fa fa-folder fa-fw',
       
'thread'   => 'fa fa-comments-o fa-fw',
       
'link'     => 'fa fa-link fa-fw',
       
'question' => 'fa fa-mortar-board fa-fw',
       
'new'      => 'fa fa-lightbulb-o fa-fw',
       
'poll'     => 'fa fa-pie-chart fa-fw',
       
'lock'     => 'fa fa-lock fa-fw',
       
'image'    => 'fa fa-file-picture-o fa-fw',
       
'file'     => 'fa fa-file-zip-o fa-fw',
       
'tracked'  => 'fa fa-bell-o fa-fw',
       
'hot'      => 'fa fa-heartbeat fa-fw',
       
'sticky'   => 'fa fa-thumb-tack fa-fw',
       
'reads'    => 'fa fa-ticket fa-fw',
    ];
   
/**
     * Get records of cached forum ranks
     *
     * @staticvar array $forum_rank_cache
     * @return array Cached forum ranks
     */
   
private static $forum_rank_cache = NULL;

    private
$forum_access = FALSE;

   
/**
     * @param string $type
     */
   
public static function getForumIcons($type = '') {
        if (isset(
self::$forum_icons[$type])) {
            return
self::$forum_icons[$type];
        }

        return
self::$forum_icons;
    }

   
/**
     * Set and Modify Forum Icons
     *
     * @param array $icons
     */
   
public static function setForumIcons(array $icons = []) {
       
self::$forum_icons = [
           
'forum'    => !empty($icons['main']) ? $icons['main'] : 'fa fa-folder fa-fw',
           
'thread'   => !empty($icons['thread']) ? $icons['thread'] : 'fa fa-chat-o fa-fw',
           
'link'     => !empty($icons['link']) ? $icons['link'] : 'fa fa-link fa-fw',
           
'question' => !empty($icons['question']) ? $icons['question'] : 'fa fa-mortar-board fa-fw',
           
'new'      => !empty($icons['new']) ? $icons['new'] : 'fa fa-lightbulb-o fa-fw',
           
'poll'     => !empty($icons['poll']) ? $icons['poll'] : 'fa fa-pie-chart fa-fw',
           
'lock'     => !empty($icons['lock']) ? $icons['lock'] : 'fa fa-lock fa-fw',
           
'image'    => !empty($icons['image']) ? $icons['image'] : 'fa fa-file-picture-o fa-fw',
           
'file'     => !empty($icons['file']) ? $icons['file'] : 'fa fa-file-zip-o fa-fw',
           
'tracked'  => !empty($icons['tracked']) ? $icons['tracked'] : 'fa fa-bell-o fa-fw',
           
'hot'      => !empty($icons['hot']) ? $icons['hot'] : 'fa fa-heartbeat fa-fw',
           
'sticky'   => !empty($icons['sticky']) ? $icons['sticky'] : 'fa fa-thumb-tack fa-fw',
           
'reads'    => !empty($icons['reads']) ? $icons['reads'] : 'fa fa-ticket fa-fw',
        ];
    }

   
/**
     * Verify Forum ID
     */
   
public static function verifyForum($forum_id) {
        if (
isnum($forum_id)) {
            return
dbcount("('forum_id')", DB_FORUMS, "forum_id='".$forum_id."' AND ".groupaccess('forum_access')." ");
        }

        return
FALSE;
    }

   
/**
     * Check all forum access
     *
     * @param mixed $forum_index
     * @param int   $forum_id
     * @param int   $thread_id
     * @param int   $user_id if provided with user_id, to check against that user
     *
     * Breaks the check and returns true for Super Administrator
     * You need to define either forum id or thread id when accessing this function
     * is non-dependent on GET against tampering (bot access)
     *
     * @return bool
     * @throws \Exception
     */
   
protected function checkForumAccess($forum_index, $forum_id = 0, $thread_id = 0, $user_id = 0) {
        if (
iSUPERADMIN) {
           
$this->forum_access = TRUE;

            return
$this->forum_access;
        }
        if (!
$forum_id or isnum($forum_id)) {
            if (
$thread_id && isnum($thread_id)) {
               
$forum_id = dbresult(dbquery("SELECT forum_id FROM ".DB_FORUM_THREADS." WHERE thread_id=:thread_id", [':thread_id' => $thread_id]), 0);
               
$list[] = $forum_id;
                if (
$ancestor = get_all_parent($forum_index, $forum_id)) {
                   
$list = array_merge_recursive($list, $ancestor);
                }

                if (!empty(
$list)) {
                   
$list_sql = implode(',', $list);
                   
$query = "SELECT forum_access FROM ".DB_FORUMS." WHERE forum_id IN ($list_sql) ORDER BY forum_cat ASC";
                   
$result = dbquery($query);
                    if (
dbrows($result)) {
                        while (
$data = dbarray($result)) {
                            if (
$user_id) {
                               
$user = fusion_get_user($user_id);
                               
$this->forum_access = checkusergroup($data['forum_access'], $user['user_level'], $user['user_groups']);
                            } else {
                               
$this->forum_access = checkgroup($data['forum_access']);
                            }
                            if (
$this->forum_access === FALSE) {
                                break;
                            }
                        }
                    }
                }
            } else {
                throw new \
Exception(fusion_get_locale('forum_4120'));
            }
        }

        return (bool)
$this->forum_access;
    }

   
/**
     * Get HTML source of forum rank images of a member
     *
     * @param int    $posts  The number of posts of the member
     * @param int    $level  The level of the member
     * @param string $groups The groups of the member
     *
     * @return string HTML source of forum rank images
     */
   
public static function showForumRank($posts, $level, $groups) {

       
$forum_settings = self::getForumSettings();

       
$ranks = [];

        if (!
$forum_settings['forum_ranks']) {
            return
'';
        }

       
$image = ($forum_settings['forum_rank_style'] == 1);

       
$forum_rank_cache = self::forumRankCache();

       
$forum_rank_css_class = [
           
USER_LEVEL_MEMBER      => 'label-member',
           
USER_LEVEL_ADMIN       => 'label-mod',
           
USER_LEVEL_SUPER_ADMIN => 'label-super-admin',
        ];

       
$forum_rank_icon_class = [
           
USER_LEVEL_MEMBER      => 'fa fa-legal fa-fw',
           
USER_LEVEL_ADMIN       => 'fa fa-legal fa-fw',
           
USER_LEVEL_SUPER_ADMIN => 'fa fa-legal fa-fw',
           
'-104'                 => 'fa fa-legal fa-fw',
        ];

       
// Moderator ranks
       
if (!empty($forum_rank_cache['mod'])) {
            if (
$level < USER_LEVEL_MEMBER) {
                foreach (
$forum_rank_cache['mod'] as $rank) {
                    if (isset(
$rank['rank_apply']) && $level == $rank['rank_apply']) {
                       
$ranks[] = $rank;
                        break;
                    }
                }
            }
        }

       
// Special ranks
       
if (!empty($forum_rank_cache['special'])) {
            if (!empty(
$groups)) {
                if (!
is_array($groups)) {
                   
$groups = explode(".", $groups);
                }

                foreach (
$forum_rank_cache['special'] as $rank) {
                    if (!isset(
$rank['rank_apply'])) {
                        continue;
                    }

                    if (
in_array($rank['rank_apply'], $groups)) {
                       
$ranks[] = $rank;
                    }
                }
            }
        }

       
// Post count ranks
       
if (!empty($forum_rank_cache['post'])) {
            if (!
$ranks) {
                foreach (
$forum_rank_cache['post'] as $rank) {
                    if (!isset(
$rank['rank_apply'])) {
                        continue;
                    }

                    if (
$posts >= $rank['rank_posts']) {
                       
$ranks['post_rank'] = $rank;
                    }
                }

                if (!
$ranks && isset($forum_rank_cache['post'][0])) {
                   
$ranks['post_rank'] = $forum_rank_cache['post'][0];
                }
            }
        }

       
// forum ranks must be the highest
       
$res = '';
        foreach (
$ranks as $rank) {
            if (
$image) {
                if (isset(
$rank['rank_title']) && isset($rank['rank_image'])) {
                   
$res .= "<span class='rank".$rank['rank_id']." rank-image'><span class='rank-title'>".$rank['rank_title']."</span> <img src='".RANKS.$rank['rank_image']."' alt='".$rank['rank_title']."'></span>";
                }
            } else {
                if (isset(
$rank['rank_apply']) && isset($rank['rank_title'])) {
                   
$font_color = get_color_brightness($rank['rank_color']) > 130 ? '#000' : '#fff';
                   
$bg = !empty($rank['rank_color']) ? " style='background:".$rank['rank_color'].";color:".$font_color."'" : '';
                   
$res .= "<span class='rank".$rank['rank_id']." rank-label label ".(isset($forum_rank_css_class[$rank['rank_apply']]) ? $forum_rank_css_class[$rank['rank_apply']] : "label-default")."'".$bg.">";
                   
$icon = !empty($rank['rank_icon']) ? $rank['rank_icon'] : '';
                   
$icon = !empty($icon) ? $icon : (isset($forum_rank_icon_class[$rank['rank_apply']]) ? $forum_rank_icon_class[$rank['rank_apply']] : "fa fa-user fa-fw");
                   
$res .= "<i class='".$icon."'></i>";
                   
$res .= "<span class='detail'>".$rank['rank_title']."</span>";
                   
$res .= "</span>";
                }
            }
        }

        return
$res;
    }

   
/**
     * Fetch Forum Settings
     *
     * @param null $key
     *
     * @return array|bool|mixed|null
     */
   
public static function getForumSettings($key = NULL) {
        if (empty(
self::$forum_settings)) {
           
self::$forum_settings = get_settings('forum');
        }

        return
$key === NULL ? self::$forum_settings : (isset(self::$forum_settings[$key]) ? self::$forum_settings[$key] : NULL);
    }

   
/**
     * Cache Forum Ranks
     *
     * @return array
     */
   
public static function forumRankCache() {

       
$forum_settings = self::getForumSettings();

       
$known_types = [
           
0 => 'post',
           
1 => 'mod'
       
];

        if (
self::$forum_rank_cache === NULL and $forum_settings['forum_ranks']) {

           
self::$forum_rank_cache = [
               
'post'    => [],
               
'mod'     => [],
               
'special' => [],
            ];

           
$cache_query = "
            SELECT *
            FROM "
.DB_FORUM_RANKS." ".(multilang_table("FR") ? "WHERE ".in_group('rank_language', LANGUAGE) : "")."
            ORDER BY rank_apply DESC, rank_posts ASC
            "
;

           
$result = dbquery($cache_query);

            while (
$data = dbarray($result)) {
               
$type = isset($known_types[$data['rank_type']]) ? $known_types[$data['rank_type']] : 'special';
               
self::$forum_rank_cache[$type][] = $data;
            }
        }

        return (array)
self::$forum_rank_cache;
    }

   
/**
     * Verify Thread ID
     *
     * @param $thread_id
     *
     * @return bool|int
     */
   
public static function verifyThread($thread_id) {
        if (
isnum($thread_id)) {
            return
dbcount("('forum_id')", DB_FORUM_THREADS, "thread_id='".$thread_id."'");
        }

        return
FALSE;
    }

   
/**
     * Verify Post ID
     *
     * @param $post_id
     *
     * @return bool|int
     */
   
public static function verifyPost($post_id) {
        if (
isnum($post_id)) {
            return
dbcount("('post_id')", DB_FORUM_POSTS, "post_id='".$post_id."'");
        }

        return
FALSE;
    }

   
/**
     * Get Recent Topics per forum.
     *
     * @param int $forum_id - all if 0.
     *
     * @return array
     */
   
public static function getRecentTopics($forum_id = 0) {
       
$forum_settings = self::getForumSettings();
       
$result = dbquery("SELECT tt.*, tf.*, tp.post_id, tp.post_datestamp,
            u.user_id, u.user_name as last_user_name, u.user_status as last_user_status, u.user_avatar as last_user_avatar,
            uc.user_id AS s_user_id, uc.user_name AS author_name, uc.user_status AS author_status, uc.user_avatar AS author_avatar,
            count(v.post_id) AS vote_count
            FROM "
.DB_FORUM_THREADS." tt
            INNER JOIN "
.DB_FORUMS." tf ON (tt.forum_id=tf.forum_id)
            LEFT JOIN "
.DB_FORUM_POSTS." tp on (tt.thread_lastpostid = tp.post_id)
            LEFT JOIN "
.DB_USERS." u ON u.user_id=tt.thread_lastuser
            LEFT JOIN "
.DB_USERS." uc ON uc.user_id=tt.thread_author
            LEFT JOIN "
.DB_FORUM_VOTES." v ON v.thread_id = tt.thread_id AND tp.post_id = v.post_id
            "
.(multilang_table("FO") ? "WHERE ".in_group('tf.forum_language', LANGUAGE)." AND" : "WHERE")."
            "
.groupaccess('tf.forum_access')." AND tt.thread_hidden='0'
            "
.($forum_id ? "AND forum_id='".intval($forum_id)."'" : '')."
            GROUP BY thread_id ORDER BY tt.thread_lastpost LIMIT 0, "
.$forum_settings['threads_per_page']."");
       
$info['rows'] = dbrows($result);
        if (
$info['rows'] > 0) {
           
// need to throw moderator as an object
           
while ($data = dbarray($result)) {
               
$data['moderators'] = Moderator::parseForumMods($data['forum_mods']);
               
$info['item'][$data['thread_id']] = $data;
            }
        }

        return
$info;
    }

   
/**
     * Moderator Instance
     *
     * @return null|Moderator
     */
   
protected function moderator() {
        if (
self::$moderator_instance === NULL) {
           
self::$moderator_instance = new Moderator();
        }

        return
self::$moderator_instance;
    }

   
/**
     * Thread Filter Instance
     *
     * @param bool $set_info
     *
     * @return null|ThreadFilter
     */
   
public static function filter($set_info = TRUE) {
        if (
self::$filter_instance === NULL) {
           
self::$filter_instance = new ThreadFilter();
            if (
$set_info == TRUE) {
               
self::$filter_instance->set_FilterInfo();
            }
        }

        return
self::$filter_instance;
    }

   
/**
     * Forum Instance
     *
     * @param bool $set_info
     *
     * @return null|Forum
     */
   
public static function forum($set_info = TRUE) {
        if (
self::$forum_instance === NULL) {
           
self::$forum_instance = new Forum();
            if (
$set_info == TRUE) {
               
self::$forum_instance->setForumInfo();
            }
        }

        return
self::$forum_instance;
    }

   
/**
     * Tag Instance
     *
     * @param bool $set_info
     * @param bool $set_title
     *
     * @return null|ThreadTags
     */
   
public static function tag($set_info = TRUE, $set_title = FALSE) {
        if (
self::$tag_instance === NULL) {
           
self::$tag_instance = new ThreadTags();
            if (
$set_info == TRUE) {
                require_once
INCLUDES."mimetypes_include.php";
               
self::$tag_instance->setTagInfo($set_title);
            }
        }

        return
self::$tag_instance;
    }

   
/**
     * Thread Instance
     *
     * @param bool $set_info
     *
     * @return null|Threads\ForumThreads
     */
   
public static function thread($set_info = TRUE) {
        if (
self::$thread_instance === NULL) {
           
self::$thread_instance = new Threads\ForumThreads();
            if (
$set_info == TRUE) {
                require_once
INCLUDES."mimetypes_include.php";
               
self::$thread_instance->setThreadInfo();
            }
        }

        return
self::$thread_instance;
    }

   
/**
     * New Thread Instance
     *
     * @param bool $set_info
     *
     * @return null|NewThread
     */
   
public static function newThread($set_info = TRUE) {
        if (
self::$new_thread_instance === NULL) {
           
self::$new_thread_instance = new NewThread();
            if (
$set_info == TRUE) {
               
self::$new_thread_instance->setNewThreadInfo();
            }
        }

        return
self::$new_thread_instance;
    }

   
/**
     * Mood Instance
     *
     * @return null|\PHPFusion\Forums\Threads\Forum_Mood
     */
   
public static function mood() {
        if (
self::$forum_mood_instance === NULL) {
           
self::$forum_mood_instance = new Forum_Mood();
        }

        return
self::$forum_mood_instance;
    }

    public static function
postify() {
        if (
self::$postify_instance === NULL) {
           
self::$postify_instance = new Forum_Postify();
        }

        return
self::$postify_instance;
    }

   
/**
     * Forum Breadcrumbs Generator
     *
     * @param array $forum_index - requires a dbquery_tree() output
     * @param int   $forum_id
     */
   
function forumBreadcrumbs(array $forum_index, $forum_id = 0) {
       
$locale = fusion_get_locale('', FORUM_LOCALE);

        if (empty(
$forum_id)) {
           
$forum_id = isset($_GET['forum_id']) && isnum($_GET['forum_id']) ? $_GET['forum_id'] : 0;
        }
       
/* Make an infinity traverse */
       
function forum_breadcrumb_arrays(array $index, $id) {
           
$crumb = [];

            if (isset(
$index[get_parent($index, $id)])) {
               
$_name = dbarray(dbquery("SELECT forum_id, forum_name, forum_cat, forum_branch FROM ".DB_FORUMS." WHERE forum_id='".$id."'"));
               
$crumb = [
                   
'link'  => INFUSIONS."forum/index.php?viewforum&amp;forum_id=".$_name['forum_id'],
                   
'title' => $_name['forum_name']
                ];
                if (isset(
$index[get_parent($index, $id)])) {
                    if (
get_parent($index, $id) == 0) {
                        return
$crumb;
                    }
                   
$crumb_1 = forum_breadcrumb_arrays($index, get_parent($index, $id));
                    if (
is_array($crumb_1)) {
                       
$crumb = array_merge_recursive($crumb, $crumb_1); // convert so can comply to Fusion Tab API.
                   
}
                }
            }

            return
$crumb;
        }

       
// then we make an infinity recursive function to loop/break it out.
       
$crumb = forum_breadcrumb_arrays($forum_index, $forum_id);
       
$title_count = !empty($crumb['title']) && is_array($crumb['title']) ? count($crumb['title']) > 1 : 0;
       
// then we sort in reverse.
       
if ($title_count) {
           
krsort($crumb['title']);
           
krsort($crumb['link']);
        }
        if (
$title_count) {
            foreach (
$crumb['title'] as $i => $value) {
               
add_breadcrumb(['link' => $crumb['link'][$i], 'title' => $value]);
                if (
$i == count($crumb['title']) - 1) {
                   
add_to_title($locale['global_201'].$value);
                }
            }
        } else if (isset(
$crumb['title'])) {
           
add_to_title($locale['global_201'].$crumb['title']);
           
add_breadcrumb(['link' => $crumb['link'], 'title' => $crumb['title']]);
        }
    }

    static function
getEditTimelimit($seconds = TRUE) {
       
$seconds = $seconds == TRUE ? 60 : 1;

        switch (
self::$forum_settings['forum_edit_timelimit']) {
            case
0: // no limit
               
$limit = 0;
                break;
            case
1: // 10 minutes
               
$limit = 10 * $seconds;
                break;
            case
2: // 30 minutes
               
$limit = 30 * $seconds;
                break;
            case
3: // 45 minutes
               
$limit = 45 * $seconds;
                break;
            case
4: // 60 minutes
               
$limit = 60 * $seconds;
                break;
            default:
               
$limit = 0;
        }

        return
$limit;
    }
}