Current File : /home/n742ef5/.trash/asgaros-forum___/includes/forum.php |
<?php
if (!defined('ABSPATH')) {
exit;
}
class AsgarosForum {
public $version = '2.7.2';
public $executePlugin = false;
public $db = null;
public $tables = null;
public $plugin_url = '';
public $plugin_path = '';
public $date_format = '';
public $time_format = '';
public $error = false;
public $current_description = false;
public $current_category = false;
public $current_forum = false;
public $current_forum_name = false;
public $current_topic = false;
public $current_topic_name = false;
public $current_post = false;
public $current_view = false;
public $current_element = false;
public $current_page = 0;
public $parent_forum = false;
public $parent_forum_name = false;
public $category_access_level = false;
public $parents_set = false;
// We need this flag if want to prevent modifications of core queries in certain cases.
public $prevent_query_modifications = false;
public $options = array();
public $options_default = array(
'forum_title' => '',
'forum_description' => '',
'location' => 0,
'posts_per_page' => 10,
'topics_per_page' => 20,
'members_per_page' => 25,
'allow_shortcodes' => false,
'embed_content' => true,
'allow_guest_postings' => false,
'allowed_filetypes' => 'jpg,jpeg,gif,png,bmp,pdf',
'allow_file_uploads' => false,
'upload_permission' => 'loggedin',
'hide_uploads_from_guests' => false,
'hide_profiles_from_guests' => false,
'uploads_maximum_number' => 5,
'uploads_maximum_size' => 5,
'uploads_maximum_size_unit' => 'MB',
'uploads_show_thumbnails' => true,
'admin_subscriptions' => false,
'allow_subscriptions' => true,
'notification_sender_name' => '',
'notification_sender_mail' => '',
'receivers_admin_notifications' => '',
'mail_template_new_post_subject' => '',
'mail_template_new_post_message' => '',
'mail_template_new_topic_subject' => '',
'mail_template_new_topic_message' => '',
'mail_template_mentioned_subject' => '',
'mail_template_mentioned_message' => '',
'allow_signatures' => false,
'signatures_permission' => 'loggedin',
'signatures_html_allowed' => false,
'signatures_html_tags' => '<br><a><i><b><u><s><img><strong>',
'enable_avatars' => true,
'enable_mentioning' => true,
'enable_mentioning_suggestions' => true,
'enable_reactions' => true,
'reactions_show_names' => true,
'enable_search' => true,
'enable_profiles' => true,
'enable_memberslist' => true,
'memberslist_filter_normal' => true,
'memberslist_filter_moderator' => true,
'memberslist_filter_administrator' => true,
'memberslist_filter_banned' => true,
'enable_rss' => false,
'load_fontawesome' => true,
'load_fontawesome_compat_v4' => true,
'count_topic_views' => true,
'reports_enabled' => true,
'reports_notifications' => true,
'memberslist_loggedin_only' => false,
'memberslist_filter_siteadmins' => false,
'show_login_button' => true,
'show_logout_button' => true,
'show_register_button' => true,
'show_who_is_online' => true,
'show_last_seen' => true,
'show_newest_member' => true,
'show_statistics' => true,
'statistics_show_online_usernames' => true,
'enable_breadcrumbs' => true,
'breadcrumbs_show_category' => true,
'highlight_admin' => true,
'highlight_authors' => true,
'show_author_posts_counter' => true,
'show_edit_date' => true,
'minimum_time_between_posts' => 30,
'enable_edit_post' => true,
'time_limit_edit_posts' => 0,
'enable_delete_post' => false,
'time_limit_delete_posts' => 180,
'enable_delete_topic' => false,
'time_limit_delete_topics' => 180,
'delete_topics_without_replies' => false,
'enable_open_topic' => false,
'enable_close_topic' => false,
'show_description_in_forum' => false,
'require_login' => false,
'require_login_posts' => false,
'create_blog_topics_id' => 0,
'approval_for' => 'guests',
'enable_activity' => true,
'activity_days' => 14,
'activities_per_page' => 50,
'enable_polls' => true,
'polls_permission' => 'loggedin',
'polls_results_visible' => false,
'enable_seo_urls' => true,
'seo_url_mode_content' => 'slug',
'seo_url_mode_profile' => 'slug',
'custom_url_login' => '',
'custom_url_register' => '',
'view_name_activity' => 'activity',
'view_name_subscriptions' => 'subscriptions',
'view_name_search' => 'search',
'view_name_forum' => 'forum',
'view_name_topic' => 'topic',
'view_name_addtopic' => 'addtopic',
'view_name_movetopic' => 'movetopic',
'view_name_addpost' => 'addpost',
'view_name_editpost' => 'editpost',
'view_name_markallread' => 'markallread',
'view_name_members' => 'members',
'view_name_profile' => 'profile',
'view_name_history' => 'history',
'view_name_unread' => 'unread',
'view_name_unapproved' => 'unapproved',
'view_name_reports' => 'reports',
'title_separator' => '-',
'enable_spoilers' => true,
'hide_spoilers_from_guests' => false,
'subforums_location' => 'above',
'enable_reputation' => true,
'reputation_level_1_posts' => 10,
'reputation_level_2_posts' => 25,
'reputation_level_3_posts' => 100,
'reputation_level_4_posts' => 250,
'reputation_level_5_posts' => 1000,
'activity_timestamp_format' => 'relative',
);
public $options_editor = array(
'media_buttons' => false,
'editor_height' => 250,
'teeny' => false,
'quicktags' => false,
);
public $cache = array(); // Used to store selected database queries.
public $rewrite = null;
public $shortcode = null;
public $reports = null;
public $profile = null;
public $editor = null;
public $reactions = null;
public $mentioning = null;
public $notifications = null;
public $appearance = null;
public $uploads = null;
public $search = null;
public $online = null;
public $content = null;
public $breadcrumbs = null;
public $activity = null;
public $memberslist = null;
public $pagination = null;
public $unread = null;
public $feed = null;
public $permissions = null;
public $approval = null;
public $spoilers = null;
public $polls = null;
public $private = null;
public function __construct() {
// Initialize database.
global $wpdb;
$database = new AsgarosForumDatabase();
$this->tables = $database->getTables();
$this->db = $wpdb;
$this->plugin_url = plugin_dir_url(__DIR__);
$this->plugin_path = plugin_dir_path(__DIR__);
$this->load_options();
$this->date_format = get_option('date_format');
$this->time_format = get_option('time_format');
add_action('wp', array($this, 'prepare'));
add_action('wp_enqueue_scripts', array($this, 'enqueue_css_js'), 10);
// Add certain classes to body-tag.
add_filter('body_class', array($this, 'add_body_classes'));
// Add filters for modifying the title of the page.
add_filter('wp_title', array($this, 'change_wp_title'), 100, 3);
add_filter('document_title_parts', array($this, 'change_document_title_parts'), 100);
add_filter('pre_get_document_title', array($this, 'change_pre_get_document_title'), 100);
add_filter('document_title_separator', array($this, 'change_document_title_separator'), 100);
add_filter('oembed_dataparse', array($this, 'prevent_oembed_dataparse'), 10, 3);
// Deleting an user.
add_action('delete_user_form', array($this, 'delete_user_form_reassign'), 10, 2);
add_action('deleted_user', array($this, 'deleted_user_reassign'), 10, 2);
// Hooks for automatic topic creation.
add_action('transition_post_status', array($this, 'post_transition_update'), 10, 3);
add_action('load-post.php', array($this, 'add_topic_meta_box_setup'));
add_action('load-post-new.php', array($this, 'add_topic_meta_box_setup'));
new AsgarosForumCompatibility($this);
new AsgarosForumStatistics($this);
new AsgarosForumUserGroups($this);
new AsgarosForumWidgets($this);
$this->rewrite = new AsgarosForumRewrite($this);
$this->shortcode = new AsgarosForumShortcodes($this);
$this->reports = new AsgarosForumReports($this);
$this->profile = new AsgarosForumProfile($this);
$this->editor = new AsgarosForumEditor($this);
$this->reactions = new AsgarosForumReactions($this);
$this->mentioning = new AsgarosForumMentioning($this);
$this->notifications = new AsgarosForumNotifications($this);
$this->appearance = new AsgarosForumAppearance($this);
$this->uploads = new AsgarosForumUploads($this);
$this->search = new AsgarosForumSearch($this);
$this->online = new AsgarosForumOnline($this);
$this->content = new AsgarosForumContent($this);
$this->breadcrumbs = new AsgarosForumBreadCrumbs($this);
$this->activity = new AsgarosForumActivity($this);
$this->memberslist = new AsgarosForumMembersList($this);
$this->pagination = new AsgarosForumPagination($this);
$this->unread = new AsgarosForumUnread($this);
$this->feed = new AsgarosForumFeed($this);
$this->permissions = new AsgarosForumPermissions($this);
$this->approval = new AsgarosForumApproval($this);
$this->spoilers = new AsgarosForumSpoilers($this);
$this->polls = new AsgarosForumPolls($this);
$this->private = new AsgarosForumPrivate($this);
}
//======================================================================
// FUNCTIONS FOR GETTING AND SETTING OPTIONS.
//======================================================================
public function load_options() {
// Get options and merge them with the default ones.
$current_options = get_option('asgarosforum_options', array());
$this->options = array_merge($this->options_default, $current_options);
// Ensure default values if some needed inputs got deleted.
if (empty($this->options['forum_title'])) {
$this->options['forum_title'] = __('Forum', 'asgaros-forum');
}
if (empty($this->options['notification_sender_name'])) {
$this->options['notification_sender_name'] = get_bloginfo('name');
}
if (empty($this->options['notification_sender_mail'])) {
$this->options['notification_sender_mail'] = get_bloginfo('admin_email');
}
if (empty($this->options['receivers_admin_notifications'])) {
$this->options['receivers_admin_notifications'] = get_bloginfo('admin_email');
}
if (empty($this->options['mail_template_new_post_subject'])) {
$this->options['mail_template_new_post_subject'] = __('New reply: ###TITLE###', 'asgaros-forum');
}
if (empty($this->options['mail_template_new_post_message'])) {
$site_link = '<a href="' . site_url() . '">' . get_bloginfo( 'name' ) . '</a>';
$message = sprintf(__('Hello ###USERNAME###,<br><br>There is a new reply in a forum topic you are subscribed to on %s.<br><br>Forum and Topic: ###FORUM###, ###TITLE###<br><br>Author: ###AUTHOR###<br><br>Reply: ###CONTENT### Visit the reply:<br>###LINK###<br><br>If you don\'t wish to receive notification emails, please unsubscribe in Forum Page > Forum Menu > Subscriptions. There you can edit your global subscription option and unsubscribe from individual forums and topics.<br><br>Please don\'t reply to this email.', 'asgaros-forum'), $site_link);
$this->options['mail_template_new_post_message'] = $message;
}
if (empty($this->options['mail_template_new_topic_subject'])) {
$this->options['mail_template_new_topic_subject'] = __('New topic: ###TITLE###', 'asgaros-forum');
}
if (empty($this->options['mail_template_new_topic_message'])) {
$site_link = '<a href="' . site_url() . '">' . get_bloginfo( 'name' ) . '</a>';
$message = sprintf(__('Hello ###USERNAME###,<br><br>There is a new topic in a forum you are subscribed to on %s.<br><br>Forum and Topic: ###FORUM###, ###TITLE###<br><br>Author: ###AUTHOR###<br><br>Content: ###CONTENT### <br>Visit the topic:<br>###LINK###<br><br>You will not receive notifications of any replies to this topic unless you globally subscribe to all "New Topics & Posts", or subscribe to this topic.<br><br>If you don\'t wish to receive these notification emails, please unsubscribe in Forum Page > Forum Menu > Subscriptions. There you can edit your global subscription option and unsubscribe from individual forums and topics.<br><br>Please don\'t reply to this email.', 'asgaros-forum'), $site_link);
$this->options['mail_template_new_topic_message'] = $message;
}
if (empty($this->options['mail_template_mentioned_subject'])) {
$this->options['mail_template_mentioned_subject'] = __('You have been mentioned!', 'asgaros-forum');
}
if (empty($this->options['mail_template_mentioned_message'])) {
$this->options['mail_template_mentioned_message'] = __('Hello ###USERNAME###,<br><br>You have been mentioned in a forum-post.<br><br>Topic:<br>###TITLE###<br><br>Author:<br>###AUTHOR###<br><br>Text:<br>###CONTENT###<br><br>Link:<br>###LINK###', 'asgaros-forum');
}
if (empty($this->options['title_separator'])) {
$this->options['title_separator'] = '-';
}
}
public function save_options($options) {
update_option('asgarosforum_options', $options);
// Reload options after saving them.
$this->load_options();
}
//======================================================================
// FUNCTIONS FOR PAGE TITLE.
//======================================================================
public function change_wp_title($title, $sep, $seplocation) {
return $this->get_title($title);
}
public function change_document_title_parts($titleParts) {
$title = empty($titleParts['title']) ? '' : $titleParts['title'];
$titleParts['title'] = $this->get_title($title);
return $titleParts;
}
public function change_pre_get_document_title($title) {
// Only modify it when a title is already set.
if (!empty($title)) {
$title = $this->get_title($title);
}
return $title;
}
public function change_document_title_separator($document_title_separator) {
if ($this->executePlugin) {
$document_title_separator = $this->get_title_separator();
}
return $document_title_separator;
}
public function get_title_separator() {
// The default title-separator is based on the forum-settings.
$title_separator = $this->options['title_separator'];
// Allow other plugins to modify the title-separator.
$title_separator = apply_filters('asgarosforum_title_separator', $title_separator);
return $title_separator;
}
public function get_title($title) {
if ($this->executePlugin) {
$metaTitle = $this->getMetaTitle();
if ($metaTitle) {
if (empty($title)) {
$title = $metaTitle;
} else {
$title_separator = $this->get_title_separator();
$title = $metaTitle.' '.$title_separator.' '.$title;
}
}
}
return $title;
}
// Gets the pages meta title.
public function getMetaTitle() {
// Get the main title by default with disabled default title generation.
$metaTitle = $this->getMainTitle(false);
// Apply custom modifications.
if (!$this->error && $this->current_view) {
if ($this->current_view === 'forum' && $this->current_forum) {
$metaTitle = $this->add_current_page_to_title($metaTitle);
} else if ($this->current_view === 'topic' && $this->current_topic) {
$metaTitle = $this->add_current_page_to_title($metaTitle);
}
}
return $metaTitle;
}
// Adds the current page to a title.
public function add_current_page_to_title($someString) {
if ($this->current_page > 0) {
$currentPage = $this->current_page + 1;
$title_separator = $this->get_title_separator();
$someString .= ' '.$title_separator.' '.__('Page', 'asgaros-forum').' '.$currentPage;
}
return $someString;
}
public function prepare() {
global $post;
if (is_a($post, 'WP_Post') && $this->shortcode->checkForShortcode($post)) {
$this->executePlugin = true;
$this->options['location'] = $post->ID;
}
do_action('asgarosforum_execution_check');
// Set all base links.
if ($this->executePlugin || get_post($this->options['location'])) {
$this->rewrite->set_links();
}
if (!$this->executePlugin) {
return;
}
// Parse the URL.
$this->rewrite->parse_url();
// Update online status.
$this->online->update_online_status();
do_action('asgarosforum_prepare');
switch ($this->current_view) {
case 'forum':
case 'addtopic':
$this->setParents($this->current_element, 'forum');
break;
case 'movetopic':
case 'topic':
case 'addpost':
$this->setParents($this->current_element, 'topic');
break;
case 'editpost':
$this->setParents($this->current_element, 'post');
break;
case 'markallread':
case 'unread':
break;
case 'subscriptions':
// Go back to the overview when this functionality is not enabled or the user is not logged-in.
if (!$this->options['allow_subscriptions'] || !is_user_logged_in()) {
$this->current_view = 'overview';
}
break;
case 'search':
// Go back to the overview when this functionality is not enabled.
if (!$this->options['enable_search']) {
$this->current_view = 'overview';
}
break;
case 'profile':
case 'history':
if (!$this->profile->functionalityEnabled()) {
$this->current_view = 'overview';
}
break;
case 'members':
// Go back to the overview when this functionality is not enabled.
if (!$this->memberslist->functionality_enabled()) {
$this->current_view = 'overview';
}
break;
case 'activity':
if (!$this->activity->functionality_enabled()) {
$this->current_view = 'overview';
}
break;
case 'unapproved':
// Ensure that the user is at least a moderator.
if (!$this->permissions->isModerator('current')) {
$this->current_view = 'overview';
}
break;
case 'reports':
// Ensure that the user is at least a moderator.
if (!$this->permissions->isModerator('current')) {
$this->current_view = 'overview';
}
break;
default:
$this->current_view = 'overview';
break;
}
$this->shortcode->handleAttributes();
// Check access.
$this->check_access();
// Override editor settings.
$this->options_editor = apply_filters('asgarosforum_filter_editor_settings', $this->options_editor);
// Prevent generation of some head-elements.
remove_action('wp_head', 'rel_canonical');
remove_action('wp_head', 'wp_shortlink_wp_head');
remove_action('wp_head', 'wp_oembed_add_discovery_links');
if (isset($_POST['submit_action'])) {
$this->content->do_insertion();
} else if (isset($_GET['move_topic'])) {
if (!empty($_REQUEST['_wpnonce'])) {
if (wp_verify_nonce(sanitize_key($_REQUEST['_wpnonce']), 'asgaros_forum_move_topic')) {
$this->moveTopic();
}
}
} else if (isset($_GET['delete_topic'])) {
if (!empty($_REQUEST['_wpnonce'])) {
if (wp_verify_nonce(sanitize_key($_REQUEST['_wpnonce']), 'asgaros_forum_delete_topic')) {
$this->delete_topic($this->current_topic);
}
}
} else if (isset($_GET['remove_post'])) {
if (!empty($_REQUEST['_wpnonce'])) {
if (wp_verify_nonce(sanitize_key($_REQUEST['_wpnonce']), 'asgaros_forum_delete_post')) {
$post_id = (!empty($_GET['post'])) ? absint($_GET['post']) : 0;
$this->remove_post($post_id);
}
}
} else if (!empty($_POST['sticky_topic']) || isset($_GET['sticky_topic'])) {
if (!empty($_REQUEST['_wpnonce'])) {
if (wp_verify_nonce(sanitize_key($_REQUEST['_wpnonce']), 'asgaros_forum_sticky_topic')) {
$sticky_mode = 1;
if (!empty($_POST['sticky_topic'])) {
$sticky_mode = (int) $_POST['sticky_topic'];
}
$this->set_sticky($this->current_topic, $sticky_mode);
}
}
} else if (isset($_GET['unsticky_topic'])) {
if (!empty($_REQUEST['_wpnonce'])) {
if (wp_verify_nonce(sanitize_key($_REQUEST['_wpnonce']), 'asgaros_forum_unsticky_topic')) {
$this->set_sticky($this->current_topic, 0);
}
}
} else if (isset($_GET['open_topic'])) {
if (!empty($_REQUEST['_wpnonce'])) {
if (wp_verify_nonce(sanitize_key($_REQUEST['_wpnonce']), 'asgaros_forum_open_topic')) {
$this->change_status('open');
}
}
} else if (isset($_GET['close_topic'])) {
if (!empty($_REQUEST['_wpnonce'])) {
if (wp_verify_nonce(sanitize_key($_REQUEST['_wpnonce']), 'asgaros_forum_close_topic')) {
$this->change_status('closed');
}
}
} else if (isset($_GET['approve_topic'])) {
if (!empty($_REQUEST['_wpnonce'])) {
if (wp_verify_nonce(sanitize_key($_REQUEST['_wpnonce']), 'asgaros_forum_approve_topic')) {
$this->approval->approve_topic($this->current_topic);
}
}
} else if (isset($_GET['subscribe_topic'])) {
if (!empty($_REQUEST['_wpnonce'])) {
if (wp_verify_nonce(sanitize_key($_REQUEST['_wpnonce']), 'asgaros_forum_subscribe_topic')) {
$topic_id = (!empty($_GET['subscribe_topic'])) ? absint($_GET['subscribe_topic']) : 0;
$this->notifications->subscribe_topic($topic_id);
}
}
} else if (isset($_GET['unsubscribe_topic'])) {
if (!empty($_REQUEST['_wpnonce'])) {
if (wp_verify_nonce(sanitize_key($_REQUEST['_wpnonce']), 'asgaros_forum_unsubscribe_topic')) {
$topic_id = (!empty($_GET['unsubscribe_topic'])) ? absint($_GET['unsubscribe_topic']) : 0;
$this->notifications->unsubscribe_topic($topic_id);
}
}
} else if (isset($_GET['subscribe_forum'])) {
if (!empty($_REQUEST['_wpnonce'])) {
if (wp_verify_nonce(sanitize_key($_REQUEST['_wpnonce']), 'asgaros_forum_subscribe_forum')) {
$forum_id = (!empty($_GET['subscribe_forum'])) ? absint($_GET['subscribe_forum']) : 0;
$this->notifications->subscribe_forum($forum_id);
}
}
} else if (isset($_GET['unsubscribe_forum'])) {
if (!empty($_REQUEST['_wpnonce'])) {
if (wp_verify_nonce(sanitize_key($_REQUEST['_wpnonce']), 'asgaros_forum_unsubscribe_forum')) {
$forum_id = (!empty($_GET['unsubscribe_forum'])) ? absint($_GET['unsubscribe_forum']) : 0;
$this->notifications->unsubscribe_forum($forum_id);
}
}
} else if (isset($_GET['report_add'])) {
if (!empty($_REQUEST['_wpnonce'])) {
if (wp_verify_nonce(sanitize_key($_REQUEST['_wpnonce']), 'asgaros_forum_report_add')) {
$post_id = (!empty($_GET['post'])) ? absint($_GET['post']) : 0;
$reporter_id = get_current_user_id();
$this->reports->add_report($post_id, $reporter_id);
}
}
} else if (!empty($_GET['report_delete']) && is_numeric($_GET['report_delete'])) {
if (!empty($_REQUEST['_wpnonce'])) {
if (wp_verify_nonce(sanitize_key($_REQUEST['_wpnonce']), 'asgaros_forum_report_delete')) {
$this->reports->remove_report(sanitize_key($_GET['report_delete']));
}
}
}
do_action('asgarosforum_prepare_'.$this->current_view);
}
public function check_access() {
// Check login access.
if ($this->options['require_login'] && !is_user_logged_in()) {
$this->error = __('Sorry, only logged-in users can access the forum.', 'asgaros-forum');
$this->error = apply_filters('asgarosforum_filter_error_message_require_login', $this->error);
return;
}
// Check category access.
$this->category_access_level = get_term_meta($this->current_category, 'category_access', true);
if ($this->category_access_level) {
if ($this->category_access_level === 'loggedin' && !is_user_logged_in()) {
$this->error = __('Sorry, only logged-in users can access this category.', 'asgaros-forum');
return;
}
if ($this->category_access_level === 'moderator' && !$this->permissions->isModerator('current')) {
$this->error = __('Sorry, you cannot access this area.', 'asgaros-forum');
return;
}
}
// Check usergroups access.
if (!AsgarosForumUserGroups::checkAccess($this->current_category)) {
$this->error = __('Sorry, you cannot access this area.', 'asgaros-forum');
return;
}
if ($this->current_view === 'topic' || $this->current_view === 'addpost') {
// Check topic-access.
if ($this->options['require_login_posts'] && !is_user_logged_in()) {
$this->error = __('Sorry, only logged-in users can access this topic.', 'asgaros-forum');
return;
}
// Check unapproved-topic access.
if (!$this->approval->is_topic_approved($this->current_topic) && !$this->permissions->isModerator('current')) {
$this->rewrite->redirect('overview');
}
}
// Check custom access.
$custom_access = apply_filters('asgarosforum_filter_check_access', true, $this->current_category);
if (!$custom_access) {
$this->error = __('Sorry, you cannot access this area.', 'asgaros-forum');
return;
}
// Add a login-notice if necessary.
if (!is_user_logged_in() && !$this->options['allow_guest_postings']) {
$show_login = $this->showLoginLink();
$show_register = $this->showRegisterLink();
$notice = '';
if ($show_login) {
$login_link = '<u><a class="'.$show_login['menu_class'].'" href="'.$show_login['menu_url'].'">'.$show_login['menu_link_text'].'</a></u>';
if ($show_register) {
$register_link = '<u><a class="'.$show_register['menu_class'].'" href="'.$show_register['menu_url'].'">'.$show_register['menu_link_text'].'</a></u>';
$notice = sprintf(esc_html__('Please %1$s or %2$s to create posts and topics.', 'asgaros-forum'), $login_link, $register_link);
} else {
$notice = sprintf(esc_html__('Please %s to create posts and topics.', 'asgaros-forum'), $login_link);
}
} else {
$notice = __('You need to log in to create posts and topics.', 'asgaros-forum');
}
$notice = apply_filters('asgarosforum_filter_login_message', $notice);
$this->add_notice($notice);
}
}
public function enqueue_css_js() {
if ($this->options['load_fontawesome']) {
wp_enqueue_style('af-fontawesome', $this->plugin_url.'libs/fontawesome/css/all.min.css', array(), $this->version);
}
if ($this->options['load_fontawesome_compat_v4']) {
wp_enqueue_style('af-fontawesome-compat-v4', $this->plugin_url.'libs/fontawesome/css/v4-shims.min.css', array(), $this->version);
}
wp_enqueue_style('af-widgets', $this->plugin_url.'skin/widgets.css', array(), $this->version);
if (!$this->executePlugin) {
return;
}
wp_enqueue_style('af-style', $this->plugin_url.'skin/style.css', array(), $this->version);
if (is_rtl()) {
wp_enqueue_style('af-rtl', $this->plugin_url.'skin/rtl.css', array(), $this->version);
}
wp_enqueue_script('asgarosforum-js', $this->plugin_url.'js/script.js', array('jquery', 'wp-api'), $this->version, false);
wp_localize_script(
'wp-api',
'wpApiSettings',
array(
'root' => esc_url_raw(rest_url()),
'nonce' => wp_create_nonce('wp_rest'),
'topicid' => absint($this->current_topic),
)
);
if ($this->options['enable_spoilers']) {
wp_enqueue_script('asgarosforum-js-spoilers', $this->plugin_url.'js/script-spoilers.js', array('jquery'), $this->version, false);
}
do_action('asgarosforum_enqueue_css_js');
}
// Add certain classes to body-tag.
public function add_body_classes($classes) {
if ($this->executePlugin) {
$classes[] = 'asgaros-forum';
$classes[] = 'asgaros-forum-'.$this->current_view;
}
return $classes;
}
// Gets the pages main title.
public function getMainTitle($setDefaultTitle = true) {
$mainTitle = false;
if ($setDefaultTitle) {
$mainTitle = stripslashes($this->options['forum_title']);
}
if (!$this->error && $this->current_view) {
if ($this->current_view === 'forum' && $this->current_forum) {
$mainTitle = esc_html(stripslashes($this->current_forum_name));
} else if ($this->current_view === 'topic' && $this->current_topic) {
$mainTitle = esc_html(stripslashes($this->current_topic_name));
} else if ($this->current_view === 'editpost') {
$mainTitle = __('Edit Post', 'asgaros-forum');
} else if ($this->current_view === 'addpost') {
$mainTitle = __('Post Reply', 'asgaros-forum').': '.esc_html(stripslashes($this->current_topic_name));
} else if ($this->current_view === 'addtopic') {
$mainTitle = __('New Topic', 'asgaros-forum');
} else if ($this->current_view === 'movetopic') {
$mainTitle = __('Move Topic', 'asgaros-forum');
} else if ($this->current_view === 'search') {
$mainTitle = __('Search', 'asgaros-forum');
} else if ($this->current_view === 'subscriptions') {
$mainTitle = __('Subscriptions', 'asgaros-forum');
} else if ($this->current_view === 'profile') {
$mainTitle = $this->profile->get_profile_title();
} else if ($this->current_view === 'history') {
$mainTitle = $this->profile->get_history_title();
} else if ($this->current_view === 'members') {
$mainTitle = __('Members', 'asgaros-forum');
} else if ($this->current_view === 'activity') {
$mainTitle = __('Activity', 'asgaros-forum');
} else if ($this->current_view === 'unread') {
$mainTitle = __('Unread Topics', 'asgaros-forum');
} else if ($this->current_view === 'unapproved') {
$mainTitle = __('Unapproved Topics', 'asgaros-forum');
} else if ($this->current_view === 'reports') {
$mainTitle = __('Reports', 'asgaros-forum');
}
}
return $mainTitle;
}
// Holds all notices.
private $notices = array();
// Adds a new notice to the notices array.
public function add_notice($notice_message, $notice_link = false, $notice_icon = false) {
$this->notices[] = array(
'message' => $notice_message,
'link' => $notice_link,
'icon' => $notice_icon,
);
}
// Renders a single given notice.
public function render_notice($notice_message, $notice_link = false, $notice_icon = false, $in_panel = false) {
if ($in_panel) { echo '<div class="notices-panel">'; }
echo '<div class="notice">';
if ($notice_icon) {
echo '<span class="notice-icon '.esc_attr($notice_icon).'"></span>';
}
if ($notice_link) { echo '<a href="'.esc_url($notice_link).'">'; }
echo wp_kses_post($notice_message);
if ($notice_link) { echo '</a>'; }
echo '</div>';
if ($in_panel) { echo '</div>'; }
}
// Renders all existing notices.
public function render_notices() {
if (!empty($this->notices)) {
echo '<div class="notices-panel">';
foreach ($this->notices as $notice) {
$this->render_notice($notice['message'], $notice['link'], $notice['icon']);
}
echo '</div>';
}
}
public function forum() {
ob_start();
echo '<div id="af-wrapper">';
do_action('asgarosforum_content_top');
do_action('asgarosforum_'.$this->current_view.'_custom_content_top');
// Show Header Area except for single posts.
if ($this->current_view !== 'post' && apply_filters('asgarosforum_filter_show_header', true)) {
$this->showHeader();
do_action('asgarosforum_content_header');
}
$this->error = apply_filters('asgarosforum_filter_error', $this->error);
if ($this->has_error()) {
$this->render_error();
} else if ($this->current_view === 'post') {
$this->showSinglePost();
} else {
$this->render_notices();
$this->showMainTitleAndDescription();
switch ($this->current_view) {
case 'search':
$this->search->show_search_results();
break;
case 'subscriptions':
$this->notifications->show_subscription_overview();
break;
case 'movetopic':
$this->showMoveTopic();
break;
case 'forum':
$this->show_forum();
break;
case 'topic':
$this->showTopic();
break;
case 'addtopic':
case 'addpost':
case 'editpost':
$this->editor->showEditor($this->current_view);
break;
case 'profile':
$this->profile->show_profile();
break;
case 'history':
$this->profile->show_history();
break;
case 'members':
$this->memberslist->show_memberslist();
break;
case 'activity':
$this->activity->show_activity();
break;
case 'unread':
$this->unread->show_unread_topics();
break;
case 'unapproved':
$this->approval->show_unapproved_topics();
break;
case 'reports':
$this->reports->show_reports();
break;
default:
$this->overview();
break;
}
// Action hook for optional bottom navigation elements.
echo '<div id="bottom-navigation">';
do_action('asgarosforum_bottom_navigation', $this->current_view);
echo '</div>';
}
do_action('asgarosforum_content_bottom');
do_action('asgarosforum_'.$this->current_view.'_custom_content_bottom');
echo '<div class="clear"></div>';
echo '</div>';
return ob_get_clean();
}
public function showMainTitleAndDescription() {
$mainTitle = $this->getMainTitle();
echo '<h1 class="main-title main-title-'.esc_attr($this->current_view).'">';
// Show lock symbol for closed topics.
if ($this->current_view == 'topic' && $this->is_topic_closed($this->current_topic)) {
echo '<span class="main-title-icon fas fa-lock"></span>';
}
echo esc_html($mainTitle);
echo '</h1>';
if ($this->current_view === 'forum' && $this->options['show_description_in_forum'] && !empty($this->current_description)) {
$forum_object = $this->content->get_forum($this->current_forum);
echo '<div class="main-description">'.esc_html(stripslashes($forum_object->description)).'</div>';
}
}
public function overview() {
$categories = $this->content->get_categories();
require 'views/overview.php';
}
public function showSinglePost() {
$counter = 0;
$topicStarter = $this->get_topic_starter($this->current_topic);
$post = $this->content->get_post($this->current_post);
require 'views/post-element.php';
}
public function show_forum() {
require 'views/forum.php';
}
public function render_forum_element($forum) {
$custom_rendering = apply_filters('asgarosforum_render_custom_forum_element_decision', false, $forum);
if ($custom_rendering === true) {
do_action('asgarosforum_render_custom_forum_element', $forum);
} else {
// Get counters and format them.
$count_topics = $this->get_forum_topic_counter($forum->id);
$count_topics_i18n = number_format_i18n($count_topics);
$count_posts = $this->get_forum_post_counter($forum->id);
$count_posts_i18n = number_format_i18n($count_posts);
// Get the read/unread status of a forum.
$unread_status = $this->unread->get_status_forum($forum->id, $count_topics);
echo '<div class="content-element forum" id="forum-'.esc_attr($forum->id).'">';
$forum_icon = trim(esc_html(stripslashes($forum->icon)));
$forum_icon = (empty($forum_icon)) ? 'fas fa-comments' : $forum_icon;
$forum_link = $this->get_link('forum', absint($forum->id));
echo '<div class="forum-status '.esc_attr($unread_status).'">';
echo '<i class="'.esc_attr($forum_icon).'"></i>';
echo '</div>';
echo '<div class="forum-name">';
echo '<a class="forum-title" href="'.esc_url($forum_link).'">';
echo esc_html(stripslashes($forum->name));
echo '</a>';
// Show the description of the forum when it is not empty.
$forum_description = stripslashes($forum->description);
if (!empty($forum_description)) {
echo '<small class="forum-description">'.esc_html($forum_description).'</small>';
}
// Show forum stats.
echo '<small class="forum-stats">';
printf(_n('%s Topic', '%s Topics', absint($count_topics), 'asgaros-forum'), esc_html($count_topics_i18n));
echo ' · ';
printf(_n('%s Post', '%s Posts', absint($count_posts), 'asgaros-forum'), esc_html($count_posts_i18n));
echo '</small>';
echo '<small class="forum-lastpost-small">';
$this->render_lastpost_in_forum($forum->id, true);
echo '</small>';
// Show subforums.
if ($forum->count_subforums > 0) {
echo '<small class="forum-subforums">';
echo '<b>'.esc_html__('Subforums', 'asgaros-forum').':</b> ';
$subforums = $this->get_forums($forum->parent_id, $forum->id);
$subforumsFirstDone = false;
foreach ($subforums as $subforum) {
echo ($subforumsFirstDone) ? ' · ' : '';
echo '<a href="'.esc_url($this->get_link('forum', absint($subforum->id))).'">'.esc_html(stripslashes($subforum->name)).'</a>';
$subforumsFirstDone = true;
}
echo '</small>';
}
echo '</div>';
do_action('asgarosforum_custom_forum_column', $forum->id);
echo '<div class="forum-poster">';
$this->render_lastpost_in_forum($forum->id);
echo '</div>';
echo '</div>';
}
do_action('asgarosforum_after_forum');
}
public function render_topic_element($topic_object, $topic_type = 'topic-normal', $show_topic_location = false) {
$lastpost_data = $this->get_lastpost_in_topic($topic_object->id);
$unread_status = $this->unread->get_status_topic($topic_object->id);
$topic_title = esc_html(stripslashes($topic_object->name));
echo '<div class="content-element topic '.esc_attr($topic_type).'">';
echo '<div class="topic-status '.esc_attr($unread_status).'"><i class="far fa-comments"></i></div>';
echo '<div class="topic-name">';
if ($this->is_topic_sticky($topic_object->id)) {
echo '<span class="topic-icon fas fa-thumbtack" title="'.esc_attr__('This topic is pinned', 'asgaros-forum').'"></span>';
}
if ($this->is_topic_closed($topic_object->id)) {
echo '<span class="topic-icon fas fa-lock" title="'.esc_attr__('This topic is closed', 'asgaros-forum').'"></span>';
}
if ($this->polls->has_poll($topic_object->id)) {
echo '<span class="topic-icon fas fa-poll-h" title="'.esc_attr__('This topic contains a poll', 'asgaros-forum').'"></span>';
}
echo '<a href="'.esc_url($this->get_link('topic', absint($topic_object->id))).'" title="'.esc_attr($topic_title).'">';
echo esc_html($topic_title);
echo '</a>';
echo '<small>';
echo esc_html__('By', 'asgaros-forum').' '.$this->getUsername($topic_object->author_id);
// Show the name of the forum in which a topic is located in. This is currently only used for search results.
if ($show_topic_location) {
echo ' · ';
echo esc_html__('In', 'asgaros-forum').' ';
echo '<a href="'.esc_url($this->rewrite->get_link('forum', absint($topic_object->forum_id))).'">';
echo esc_html(stripslashes($topic_object->forum_name));
echo '</a>';
}
$this->pagination->renderTopicOverviewPagination($topic_object->id, ($topic_object->answers + 1));
echo '</small>';
// Show topic stats.
echo '<small class="topic-stats">';
$count_answers_i18n = number_format_i18n($topic_object->answers);
printf(_n('%s Reply', '%s Replies', absint($topic_object->answers), 'asgaros-forum'), esc_html($count_answers_i18n));
if ($this->options['count_topic_views']) {
$count_views_i18n = number_format_i18n($topic_object->views);
echo ' · ';
printf(_n('%s View', '%s Views', absint($topic_object->views), 'asgaros-forum'), esc_html($count_views_i18n));
}
echo '</small>';
// Show lastpost info.
echo '<small class="topic-lastpost-small">';
$this->render_lastpost_in_topic($topic_object->id, true);
echo '</small>';
echo '</div>';
do_action('asgarosforum_custom_topic_column', $topic_object->id);
echo '<div class="topic-poster">';
$this->render_lastpost_in_topic($topic_object->id);
echo '</div>';
echo '</div>';
do_action('asgarosforum_after_topic');
}
// Renders all subforums inside of a category/forum combination.
public function render_subforums($category_id, $forum_id) {
$subforums = $this->get_forums($category_id, $forum_id);
if (!empty($subforums)) {
echo '<div class="title-element">';
echo esc_html__('Subforums', 'asgaros-forum');
echo '<span class="last-post-headline">'.esc_html__('Last post', 'asgaros-forum').'</span>';
echo '</div>';
echo '<div class="content-container">';
foreach ($subforums as $forum) {
$this->render_forum_element($forum);
}
echo '</div>';
}
}
public function showTopic() {
// Create a unique slug for this topic if necessary.
$topic = $this->content->get_topic($this->current_topic);
if (empty($topic->slug)) {
$slug = $this->rewrite->create_unique_slug($topic->name, $this->tables->topics, 'topic');
$this->db->update($this->tables->topics, array('slug' => $slug), array('id' => $topic->id), array('%s'), array('%d'));
}
// Get posts of topic.
$posts = $this->get_posts();
if ($posts) {
$this->incrementTopicViews();
$this->polls->render_poll($this->current_topic);
$this->render_sticky_panel();
echo '<div class="pages-and-menu">';
$paginationRendering = $this->pagination->renderPagination($this->tables->posts, $this->current_topic);
echo $paginationRendering;
echo $this->show_topic_menu();
echo '<div class="clear"></div>';
echo '</div>';
$counter = 0;
$topicStarter = $this->get_topic_starter($this->current_topic);
foreach ($posts as $post) {
require 'views/post-element.php';
}
$this->editor->showEditor('addpost', true);
echo '<div class="pages-and-menu">';
echo $paginationRendering;
echo $this->show_topic_menu(false);
echo '<div class="clear"></div>';
echo '</div>';
} else {
echo '<div class="pages-and-menu">';
// Render delete-button for empty topics.
$current_user_id = get_current_user_id();
if ($this->permissions->can_delete_topic($current_user_id, $this->current_topic)) {
$delete_topic_link = $this->get_link('topic', $this->current_topic, array(
'delete_topic' => 1,
'_wpnonce' => wp_create_nonce('asgaros_forum_delete_topic'),
));
echo '<div class="forum-menu">';
echo '<a class="button button-red" href="'.esc_url($delete_topic_link).'" onclick="return confirm(\''.esc_attr__('Are you sure you want to remove this?', 'asgaros-forum').'\');">';
echo '<span class="menu-icon fas fa-trash-alt"></span>';
echo esc_html__('Delete', 'asgaros-forum');
echo '</a>';
echo '</div>';
}
echo '<div class="clear"></div>';
echo '</div>';
// Show notice that this topic has no posts.
$this->render_notice(__('Sorry, but there are no posts.', 'asgaros-forum'));
}
}
public function incrementTopicViews() {
if ($this->options['count_topic_views']) {
$this->db->query($this->db->prepare("UPDATE {$this->tables->topics} SET views = views + 1 WHERE id = %d", $this->current_topic));
}
}
public function showMoveTopic() {
if ($this->permissions->isModerator('current')) {
echo '<form method="post" action="'.esc_url($this->get_link('movetopic', absint($this->current_topic), array(
'move_topic' => 1,
'_wpnonce' => wp_create_nonce('asgaros_forum_move_topic'),
))).'">';
echo '<div class="title-element">'.sprintf(__('Move "<strong>%s</strong>" to new forum:', 'asgaros-forum'), esc_html(stripslashes($this->current_topic_name))).'</div>';
echo '<div class="content-container">';
echo '<br><select name="newForumID">';
$categories = $this->content->get_categories();
if ($categories) {
foreach ($categories as $category) {
$forums = $this->get_forums($category->term_id, 0);
if ($forums) {
foreach ($forums as $forum) {
echo '<option value="'.esc_attr($forum->id).'"'.($forum->id == $this->current_forum ? ' selected="selected"' : '').'>'.esc_html($forum->name).'</option>';
if ($forum->count_subforums > 0) {
$subforums = $this->get_forums($category->term_id, $forum->id);
foreach ($subforums as $subforum) {
echo '<option value="'.esc_attr($subforum->id).'"'.($subforum->id == $this->current_forum ? ' selected="selected"' : '').'>— '.esc_html($subforum->name).'</option>';
}
}
}
}
}
}
echo '</select><br><input class="button button-normal" type="submit" value="'.esc_attr__('Move', 'asgaros-forum').'"><br><br></div></form>';
} else {
$this->render_notice(__('You are not allowed to move topics.', 'asgaros-forum'));
}
}
public function get_category_name($category_id) {
$category = get_term($category_id, 'asgarosforum-category');
if ($category) {
return $category->name;
} else {
return false;
}
}
public $topic_counter_cache = null;
public function get_topic_counts() {
// If the cache is not set yet, create it.
if ($this->topic_counter_cache === null) {
// Initialize array.
$this->topic_counter_cache = array();
// Get all topic-counters of each forum first.
$topic_counters = $this->db->get_results("SELECT parent_id AS forum_id, COUNT(*) AS topic_counter FROM {$this->tables->topics} WHERE approved = 1 GROUP BY parent_id;");
$topic_counters = apply_filters('asgarosforum_overwrite_topic_counter_cache', $topic_counters);
// Assign topic-counter for each forum.
if (!empty($topic_counters)) {
foreach ($topic_counters as $counter) {
$this->topic_counter_cache[$counter->forum_id] = $counter->topic_counter;
}
}
// Now get all subforums.
$subforums = $this->content->get_all_subforums();
// Re-assign topic-counter for each forum based on the topic-counters in its subforums.
if (!empty($subforums)) {
foreach ($subforums as $subforum) {
// Continue if the subforum has no topics.
if (!isset($this->topic_counter_cache[$subforum->id])) {
continue;
}
// Re-assign value when the parent-forum has no topics.
if (!isset($this->topic_counter_cache[$subforum->parent_forum])) {
$this->topic_counter_cache[$subforum->parent_forum] = $this->topic_counter_cache[$subforum->id];
continue;
}
// Otherwise add subforum-topics to the counter of the parent forum.
$this->topic_counter_cache[$subforum->parent_forum] = ($this->topic_counter_cache[$subforum->parent_forum] + $this->topic_counter_cache[$subforum->id]);
}
}
}
return $this->topic_counter_cache;
}
public function get_forum_topic_counter($forum_id) {
$counters = $this->get_topic_counts();
if (isset($counters[$forum_id])) {
return (int) $counters[$forum_id];
} else {
return 0;
}
}
public $post_counters_cache = null;
public function get_post_counters() {
// If the cache is not set yet, create it.
if ($this->post_counters_cache === null) {
// Initialize array.
$this->post_counters_cache = array();
// Get all post-counters of each forum first.
$post_counters = $this->db->get_results("SELECT t.parent_id AS forum_id, COUNT(*) AS post_counter FROM {$this->tables->posts} AS p, {$this->tables->topics} AS t WHERE p.parent_id = t.id AND t.approved = 1 GROUP BY t.parent_id;");
$post_counters = apply_filters('asgarosforum_overwrite_post_counter_cache', $post_counters);
// Assign post-counter for each forum.
if (!empty($post_counters)) {
foreach ($post_counters as $counter) {
$this->post_counters_cache[$counter->forum_id] = $counter->post_counter;
}
}
// Now get all subforums.
$subforums = $this->content->get_all_subforums();
// Re-assign post-counter for each forum based on the post-counters in its subforums.
if (!empty($subforums)) {
foreach ($subforums as $subforum) {
// Continue if the subforum has no posts.
if (!isset($this->post_counters_cache[$subforum->id])) {
continue;
}
// Re-assign value when the parent-forum has no posts.
if (!isset($this->post_counters_cache[$subforum->parent_forum])) {
$this->post_counters_cache[$subforum->parent_forum] = $this->post_counters_cache[$subforum->id];
continue;
}
// Otherwise add subforum-posts to the counter of the parent forum.
$this->post_counters_cache[$subforum->parent_forum] = ($this->post_counters_cache[$subforum->parent_forum] + $this->post_counters_cache[$subforum->id]);
}
}
}
return $this->post_counters_cache;
}
public function get_forum_post_counter($forum_id) {
$counters = $this->get_post_counters();
if (isset($counters[$forum_id])) {
return (int) $counters[$forum_id];
} else {
return 0;
}
}
public function get_forums($id = false, $parent_forum = 0, $output_type = OBJECT) {
if ($id) {
$query_count_subforums = "SELECT COUNT(*) FROM {$this->tables->forums} WHERE parent_forum = f.id";
return $this->db->get_results($this->db->prepare("SELECT f.*, ({$query_count_subforums}) AS count_subforums FROM {$this->tables->forums} AS f WHERE f.parent_id = %d AND f.parent_forum = %d ORDER BY f.sort ASC;", $id, $parent_forum), $output_type);
}
}
public function get_subforums($forum_id, $output_type = OBJECT) {
return $this->db->get_results($this->db->prepare("SELECT * FROM {$this->tables->forums} WHERE parent_forum = %d ORDER BY sort ASC;", $forum_id), $output_type);
}
public function getSpecificForums($ids) {
$results = $this->db->get_results("SELECT id, parent_id AS category_id, name FROM {$this->tables->forums} WHERE id IN (".implode(',', $ids).') ORDER BY id ASC;');
return $results;
}
public function getSpecificTopics($ids) {
$results = $this->db->get_results("SELECT t.id, f.parent_id AS category_id, t.name FROM {$this->tables->topics} AS t LEFT JOIN {$this->tables->forums} AS f ON (f.id = t.parent_id) WHERE t.id IN (".implode(',', $ids).') ORDER BY t.id ASC;');
return $results;
}
public function get_posts() {
$start = $this->current_page * $this->options['posts_per_page'];
$end = $this->options['posts_per_page'];
$order = apply_filters('asgarosforum_filter_get_posts_order', 'p1.id ASC');
$results = $this->db->get_results($this->db->prepare("SELECT p1.id, p1.text, p1.date, p1.date_edit, p1.author_id, p1.author_edit, (SELECT COUNT(*) FROM {$this->tables->posts} AS p2 WHERE p2.author_id = p1.author_id) AS author_posts, p1.uploads FROM {$this->tables->posts} AS p1 WHERE p1.parent_id = %d ORDER BY {$order} LIMIT %d, %d;", $this->current_topic, $start, $end));
$results = apply_filters('asgarosforum_filter_get_posts', $results);
return $results;
}
private $is_first_post_cache = array();
public function is_first_post($post_id, $topic_id = false) {
// When we dont know the topic-id, we need to figure it out.
if (!$topic_id) {
// Check if there exists an current-topic-id.
if ($this->current_topic) {
$topic_id = $this->current_topic;
}
}
if (empty($this->is_first_post_cache[$topic_id])) {
$this->is_first_post_cache[$topic_id] = $this->db->get_var("SELECT id FROM {$this->tables->posts} WHERE parent_id = {$topic_id} ORDER BY id ASC LIMIT 1;");
}
if ($post_id == $this->is_first_post_cache[$topic_id]) {
return true;
} else {
return false;
}
}
public function cut_string($originalString, $length = 33, $at_next_space = false) {
$string_length = 0;
// Get string-length first.
if (function_exists('mb_strlen')) {
$string_length = mb_strlen($originalString, 'UTF-8');
} else {
$string_length = strlen($originalString);
}
// Only cut string if it is longer than defined.
if ($string_length > $length) {
// Try to find position of next space if necessary.
if ($at_next_space) {
$space_position = false;
// Get position of space.
if (function_exists('mb_strpos')) {
$space_position = mb_strpos($originalString, ' ', $length, 'UTF-8');
} else {
$space_position = strpos($originalString, ' ', $length);
}
if ($space_position) {
$length = $space_position;
} else {
return $originalString;
}
}
// Return substring.
if (function_exists('mb_substr')) {
return mb_substr($originalString, 0, $length, 'UTF-8').' …';
} else {
return substr($originalString, 0, $length).' …';
}
}
return $originalString;
}
// TODO: Clean up the complete username logic ...
public function get_plain_username($user_id) {
if ($user_id) {
$user = get_userdata($user_id);
if ($user) {
return $user->display_name;
} else {
return __('Deleted user', 'asgaros-forum');
}
} else {
return __('Guest', 'asgaros-forum');
}
}
/**
* Returns and caches a username.
*/
public $cacheGetUsername = array();
public function getUsername($user_id) {
if ($user_id) {
if (empty($this->cacheGetUsername[$user_id])) {
$user = get_userdata($user_id);
if ($user) {
$this->cacheGetUsername[$user_id] = $this->renderUsername($user);
} else {
$this->cacheGetUsername[$user_id] = __('Deleted user', 'asgaros-forum');
}
}
return $this->cacheGetUsername[$user_id];
} else {
return __('Guest', 'asgaros-forum');
}
}
/**
* Renders a username.
*/
public function renderUsername($user, $custom_name = false) {
// Add filter to change username
$user_name = apply_filters('asgarosforum_filter_username', $user->display_name, $user);
if ($custom_name) {
$user_name = $custom_name;
}
$renderedUserName = $user_name;
// Generate profile link.
$profile_link = $this->profile->getProfileLink($user);
if ($profile_link === false) {
$profile_link = '#';
}
// Highlight the usernames of administrators/moderators.
$username_highlight = 'highlight-default';
if ($this->options['highlight_admin']) {
if ($this->permissions->isAdministrator($user->ID)) {
$username_highlight = 'highlight-admin';
} else if ($this->permissions->isModerator($user->ID)) {
$username_highlight = 'highlight-moderator';
}
}
// Generate output.
$renderedUserName = '<a class="profile-link '.$username_highlight.'" href="'.$profile_link.'">'.$user_name.'</a>';
return $renderedUserName;
}
private $lastpost_forum_cache = null;
public function lastpost_forum_cache() {
if ($this->lastpost_forum_cache === null) {
// Initialize array.
$this->lastpost_forum_cache = array();
// Get all lastpost-elements of each forum first. Selection on topics is needed here because we only want posts of approved topics.
$lastpost_elements = $this->db->get_results("SELECT t.parent_id AS forum_id, MAX(p.id) AS id FROM {$this->tables->posts} AS p, {$this->tables->topics} AS t WHERE p.parent_id = t.id AND t.approved = 1 GROUP BY t.parent_id;");
// Assign lastpost-ids for each forum.
if (!empty($lastpost_elements)) {
foreach ($lastpost_elements as $element) {
$this->lastpost_forum_cache[$element->forum_id] = $element->id;
}
}
$this->lastpost_forum_cache = apply_filters('asgarosforum_overwrite_lastpost_forum_cache', $this->lastpost_forum_cache);
// Now get all subforums.
$subforums = $this->content->get_all_subforums();
// Re-assign lastpost-ids for each forum based on the lastposts in its subforums.
if (!empty($subforums)) {
foreach ($subforums as $subforum) {
// Continue if the subforum has no posts.
if (!isset($this->lastpost_forum_cache[$subforum->id])) {
continue;
}
// Re-assign value when the parent-forum has no posts.
if (!isset($this->lastpost_forum_cache[$subforum->parent_forum])) {
$this->lastpost_forum_cache[$subforum->parent_forum] = $this->lastpost_forum_cache[$subforum->id];
}
// Otherwise re-assign value when a subforum has a more recent post.
if ($this->lastpost_forum_cache[$subforum->id] > $this->lastpost_forum_cache[$subforum->parent_forum]) {
$this->lastpost_forum_cache[$subforum->parent_forum] = $this->lastpost_forum_cache[$subforum->id];
}
}
}
}
}
private $get_lastpost_in_forum_cache = array();
public function get_lastpost_in_forum($forum_id) {
if (!isset($this->get_lastpost_in_forum_cache[$forum_id])) {
$this->lastpost_forum_cache();
if (isset($this->lastpost_forum_cache[$forum_id])) {
$this->get_lastpost_in_forum_cache[$forum_id] = $this->db->get_row("SELECT p.id, p.date, p.parent_id, p.author_id, t.name FROM {$this->tables->posts} AS p, {$this->tables->topics} AS t WHERE p.id = ".$this->lastpost_forum_cache[$forum_id].' AND t.id = p.parent_id;');
} else {
$this->get_lastpost_in_forum_cache[$forum_id] = false;
}
}
return $this->get_lastpost_in_forum_cache[$forum_id];
}
public function render_lastpost_in_forum($forum_id, $compact = false) {
$lastpost = $this->get_lastpost_in_forum($forum_id);
if ($lastpost === false) {
echo '<small class="no-topics">'.esc_html__('No topics yet!', 'asgaros-forum').'</small>';
} else {
$post_link = $this->rewrite->get_post_link($lastpost->id, $lastpost->parent_id);
if ($compact === true) {
echo esc_html__('Last post:', 'asgaros-forum');
echo ' ';
echo '<a href="'.esc_url($post_link).'">'.esc_html($this->cut_string(stripslashes($lastpost->name), 34)).'</a>';
echo ' · ';
echo '<a href="'.esc_url($post_link).'">'.esc_html($this->get_activity_timestamp($lastpost->date)).'</a>';
echo ' · ';
echo $this->getUsername($lastpost->author_id);
} else {
// Avatar
if ($this->options['enable_avatars']) {
echo '<div class="forum-poster-avatar">'.get_avatar($lastpost->author_id, 40, '', '', array('force_display' => true)).'</div>';
}
// Summary
echo '<div class="forum-poster-summary">';
echo '<a href="'.esc_url($post_link).'">'.esc_html($this->cut_string(stripslashes($lastpost->name), 25)).'</a><br>';
echo '<small>';
echo '<a href="'.esc_url($post_link).'">'.esc_html($this->get_activity_timestamp($lastpost->date)).'</a>';
echo '<span> · </span>';
echo $this->getUsername($lastpost->author_id);
echo '</small>';
echo '</div>';
}
}
}
public function get_lastpost_in_topic($topic_id) {
if (empty($this->cache['get_lastpost_in_topic'][$topic_id])) {
$this->cache['get_lastpost_in_topic'][$topic_id] = $this->db->get_row("SELECT id, date, author_id, parent_id FROM {$this->tables->posts} WHERE parent_id = {$topic_id} ORDER BY id DESC LIMIT 1;");
}
return $this->cache['get_lastpost_in_topic'][$topic_id];
}
public function render_lastpost_in_topic($topic_id, $compact = false) {
$lastpost = $this->get_lastpost_in_topic($topic_id);
// Ensure that a lastpost exists. This is a required check in case a topic is empty due to problems during post-creation.
if (!empty($lastpost)) {
$post_link = $this->rewrite->get_post_link($lastpost->id, $lastpost->parent_id);
if ($compact === true) {
echo esc_html__('Last post:', 'asgaros-forum');
echo ' ';
echo '<a href="'.esc_url($post_link).'">'.esc_html($this->get_activity_timestamp($lastpost->date)).'</a>';
echo ' · ';
echo $this->getUsername($lastpost->author_id);
} else {
// Avatar
if ($this->options['enable_avatars']) {
echo '<div class="topic-poster-avatar">'.get_avatar($lastpost->author_id, 40, '', '', array('force_display' => true)).'</div>';
}
// Summary
echo '<div class="forum-poster-summary">';
echo '<a href="'.esc_url($post_link).'">'.esc_html($this->get_activity_timestamp($lastpost->date)).'</a><br>';
echo '<small>';
echo $this->getUsername($lastpost->author_id);
echo '</small>';
echo '</div>';
}
}
}
public function get_topic_starter($topic_id) {
return $this->db->get_var($this->db->prepare("SELECT author_id FROM {$this->tables->topics} WHERE id = %d;", $topic_id));
}
public function format_date($date, $full = true) {
if ($full) {
return date_i18n($this->date_format.', '.$this->time_format, strtotime($date));
} else {
return date_i18n($this->date_format, strtotime($date));
}
}
public function current_time() {
return current_time('Y-m-d H:i:s');
}
// Returns the timestamp of an activity based on the settings (relative or actual timestamp).
public function get_activity_timestamp($timestamp, $force = false) {
$timestamp_mode = ($force === false) ? $this->options['activity_timestamp_format'] : $force;
switch ($timestamp_mode) {
case 'relative':
return sprintf(__('%s ago', 'asgaros-forum'), human_time_diff(strtotime($timestamp), current_time('timestamp')));
case 'actual':
return $this->format_date($timestamp, true);
}
}
public function get_post_author($post_id) {
return $this->db->get_var($this->db->prepare("SELECT author_id FROM {$this->tables->posts} WHERE id = %d;", $post_id));
}
public function get_post_date($post_id) {
return $this->db->get_var($this->db->prepare("SELECT `date` FROM {$this->tables->posts} WHERE id = %d;", $post_id));
}
// Returns the topics created by a user.
public function countTopicsByUser($user_id) {
return $this->db->get_var("SELECT COUNT(*) FROM {$this->tables->topics} WHERE author_id = {$user_id};");
}
public function countPostsByUser($userID) {
return $this->db->get_var("SELECT COUNT(*) FROM {$this->tables->posts} WHERE author_id = {$userID};");
}
public function render_sticky_panel() {
// Cancel if the current user is not at least a moderator.
if (!$this->permissions->isModerator('current')) {
return;
}
echo '<div id="sticky-panel">';
echo '<div class="title-element title-element-dark">';
echo '<span class="title-element-icon fas fa-thumbtack"></span>';
echo esc_html__('Select Sticky Mode:', 'asgaros-forum');
echo '</div>';
echo '<div class="content-container">';
echo '<form method="post" action="'.esc_url($this->get_link('topic', absint($this->current_topic), array('_wpnonce' => wp_create_nonce('asgaros_forum_sticky_topic')))).'">';
echo '<div class="action-panel">';
echo '<label class="action-panel-option">';
echo '<input type="radio" name="sticky_topic" value="1">';
echo '<span class="action-panel-title">';
echo '<span class="action-panel-icon fas fa-thumbtack"></span>';
echo esc_html__('Sticky', 'asgaros-forum');
echo '</span>';
echo '<span class="action-panel-description">';
esc_html_e('The topic will be pinned to the current forum.', 'asgaros-forum');
echo '</span>';
echo '</label>';
echo '<label class="action-panel-option">';
echo '<input type="radio" name="sticky_topic" value="2">';
echo '<span class="action-panel-title">';
echo '<span class="action-panel-icon fas fa-globe-europe"></span>';
echo esc_html__('Global Sticky', 'asgaros-forum');
echo '</span>';
echo '<span class="action-panel-description">';
esc_html_e('The topic will be pinned to all forums.', 'asgaros-forum');
echo '</span>';
echo '</label>';
echo '</div>';
echo '</form>';
echo '</div>';
echo '</div>';
}
// Generate forum menu.
public function showForumMenu() {
$menu = '';
if ($this->forumIsOpen()) {
if ((is_user_logged_in() && !$this->permissions->isBanned('current')) || (!is_user_logged_in() && $this->options['allow_guest_postings'])) {
// New topic button.
$menu .= '<div class="forum-menu">';
$menu .= '<a class="button button-normal forum-editor-button" href="'.$this->get_link('addtopic', $this->current_forum).'">';
$menu .= '<span class="menu-icon fas fa-plus-square"></span>';
$menu .= __('New Topic', 'asgaros-forum');
$menu .= '</a>';
$menu .= '</div>';
}
}
$menu = apply_filters('asgarosforum_filter_forum_menu', $menu);
return $menu;
}
// Generate topic menu.
public function show_topic_menu($show_all_buttons = true) {
$menu = '';
$current_user_id = get_current_user_id();
if ($this->permissions->can_delete_topic($current_user_id, $this->current_topic) && $show_all_buttons) {
// Delete button.
$delete_topic_link = $this->get_link('topic', $this->current_topic, array(
'delete_topic' => 1,
'_wpnonce' => wp_create_nonce('asgaros_forum_delete_topic'),
));
$menu .= '<a class="button button-red" href="'.$delete_topic_link.'" onclick="return confirm(\''.__('Are you sure you want to remove this?', 'asgaros-forum').'\');">';
$menu .= '<span class="menu-icon fas fa-trash-alt"></span>';
$menu .= __('Delete', 'asgaros-forum');
$menu .= '</a>';
}
// Show reply and certain moderation-buttons only for approved topics.
if ($this->approval->is_topic_approved($this->current_topic)) {
if ($show_all_buttons) {
if ($this->permissions->isModerator('current')) {
// Move button.
$menu .= '<a class="button button-neutral" href="'.$this->get_link('movetopic', $this->current_topic).'">';
$menu .= '<span class="menu-icon fas fa-random"></span>';
$menu .= __('Move', 'asgaros-forum');
$menu .= '</a>';
if ($this->permissions->can_pin_topic($current_user_id, $this->current_topic)) {
if ($this->is_topic_sticky($this->current_topic)) {
// Undo sticky button.
$menu .= '<a class="button button-neutral topic-button-unsticky" href="'.$this->get_link('topic', $this->current_topic, array(
'unsticky_topic' => 1,
'_wpnonce' => wp_create_nonce('asgaros_forum_unsticky_topic'),
)).'">';
$menu .= '<span class="menu-icon fas fa-thumbtack"></span>';
$menu .= __('Unsticky', 'asgaros-forum');
$menu .= '</a>';
} else {
// Sticky button.
$menu .= '<a class="button button-neutral topic-button-sticky" href="'.$this->get_link('topic', $this->current_topic, array(
'sticky_topic' => 1,
'_wpnonce' => wp_create_nonce('asgaros_forum_sticky_topic'),
)).'">';
$menu .= '<span class="menu-icon fas fa-thumbtack"></span>';
$menu .= __('Sticky', 'asgaros-forum');
$menu .= '</a>';
}
}
}
if ($this->is_topic_closed($this->current_topic)) {
// Open button.
if ($this->permissions->can_open_topic($current_user_id, $this->current_topic)) {
$menu .= '<a class="button button-neutral" href="'.$this->get_link('topic', $this->current_topic, array(
'open_topic' => 1,
'_wpnonce' => wp_create_nonce('asgaros_forum_open_topic'),
)).'">';
$menu .= '<span class="menu-icon fas fa-unlock"></span>';
$menu .= __('Open', 'asgaros-forum');
$menu .= '</a>';
}
} else if ($this->permissions->can_close_topic($current_user_id, $this->current_topic)) {
// Close button.
$menu .= '<a class="button button-neutral" href="'.$this->get_link('topic', $this->current_topic, array(
'close_topic' => 1,
'_wpnonce' => wp_create_nonce('asgaros_forum_close_topic'),
)).'">';
$menu .= '<span class="menu-icon fas fa-lock"></span>';
$menu .= __('Close', 'asgaros-forum');
$menu .= '</a>';
}
}
if ($this->permissions->can_create_post($current_user_id)) {
// Reply button.
$menu .= '<a class="button button-normal forum-editor-button" href="'.$this->get_link('addpost', $this->current_topic).'">';
$menu .= '<span class="menu-icon fas fa-comment-dots"></span>';
$menu .= __('Reply', 'asgaros-forum');
$menu .= '</a>';
}
} else if ($this->permissions->isModerator('current') && $show_all_buttons) {
// Approve button.
if (!$this->approval->is_topic_approved($this->current_topic)) {
$menu .= '<a class="button button-green" href="'.$this->get_link('topic', $this->current_topic, array(
'approve_topic' => 1,
'_wpnonce' => wp_create_nonce('asgaros_forum_approve_topic'),
)).'">';
$menu .= '<span class="menu-icon fas fa-check"></span>';
$menu .= __('Approve', 'asgaros-forum');
$menu .= '</a>';
}
}
$menu = (!empty($menu)) ? '<div class="forum-menu">'.$menu.'</div>' : $menu;
$menu = apply_filters('asgarosforum_filter_topic_menu', $menu);
return $menu;
}
// Generate post menu.
public function show_post_menu($post_id, $author_id, $counter, $post_date) {
$menu = '';
// Only show post-menu when the topic is approved.
if ($this->approval->is_topic_approved($this->current_topic)) {
if (is_user_logged_in()) {
$current_user_id = get_current_user_id();
if ($this->permissions->can_delete_post($current_user_id, $post_id, $author_id, $post_date) && ($counter > 1 || $this->current_page >= 1)) {
// Delete button.
$delete_post_link = $this->get_link('topic', $this->current_topic, array(
'post' => $post_id,
'remove_post' => 1,
'_wpnonce' => wp_create_nonce('asgaros_forum_delete_post'),
));
$menu .= '<a class="delete-forum-post" onclick="return confirm(\''.__('Are you sure you want to remove this?', 'asgaros-forum').'\');" href="'.$delete_post_link.'">';
$menu .= '<span class="menu-icon fas fa-trash-alt"></span>';
$menu .= __('Delete', 'asgaros-forum');
$menu .= '</a>';
}
if ($this->permissions->can_edit_post($current_user_id, $post_id, $author_id, $post_date)) {
// Edit button.
$menu .= '<a href="'.$this->get_link('editpost', $post_id, array('part' => ($this->current_page + 1))).'">';
$menu .= '<span class="menu-icon fas fa-pencil-alt"></span>';
$menu .= __('Edit', 'asgaros-forum');
$menu .= '</a>';
}
}
if ($this->permissions->isModerator('current') || (!$this->is_topic_closed($this->current_topic) && ((is_user_logged_in() && !$this->permissions->isBanned('current')) || (!is_user_logged_in() && $this->options['allow_guest_postings'])))) {
// Quote button.
$menu .= '<a class="forum-editor-quote-button" data-value-id="'.$post_id.'" href="'.$this->get_link('addpost', $this->current_topic, array('quote' => $post_id)).'">';
$menu .= '<span class="menu-icon fas fa-quote-left"></span>';
$menu .= __('Quote', 'asgaros-forum');
$menu .= '</a>';
}
}
// Show report button.
$menu .= $this->reports->render_report_button($post_id, $this->current_topic);
$menu = (!empty($menu)) ? '<div class="forum-post-menu">'.$menu.'</div>' : $menu;
$menu = apply_filters('asgarosforum_filter_post_menu', $menu);
return $menu;
}
public function showHeader() {
echo '<div id="forum-header">';
echo '<div id="forum-navigation-mobile">';
echo '<a>';
echo '<span class="fas fa-bars"></span>';
echo esc_html__('Menu', 'asgaros-forum');
echo '</a>';
echo '</div>';
echo '<span class="screen-reader-text">'.esc_html__('Forum Navigation', 'asgaros-forum').'</span>';
echo '<div id="forum-navigation">';
/**
* $menu_entries = array(
* array(
* 'menu_class' => 'HTML Class'
* 'menu_link_text' => 'Link Text',
* 'menu_url' => '/url',
* 'menu_login_status' => '0', (0 = all, 1 = only logged in, 2 = only logged out)
* 'menu_new_tab' => true (true = open in new tab, false = open in same tab)
* )
* );
*/
$menu_entries = array();
$menu_entries['home'] = $this->homeLink();
$menu_entries['profile'] = $this->profile->myProfileLink();
$menu_entries['memberslist'] = $this->memberslist->show_memberslist_link();
$menu_entries['subscription'] = $this->notifications->show_subscription_overview_link();
$menu_entries['activity'] = $this->activity->show_activity_link();
$menu_entries['login'] = $this->showLoginLink();
$menu_entries['register'] = $this->showRegisterLink();
$menu_entries['logout'] = $this->showLogoutLink();
// Apply filter to menu entries
$menu_entries = apply_filters('asgarosforum_filter_header_menu', $menu_entries);
$this->drawMenuEntries($menu_entries);
do_action('asgarosforum_custom_header_menu');
echo '</div>';
$this->search->show_search_input();
echo '<div class="clear"></div>';
echo '</div>';
$this->breadcrumbs->show_breadcrumbs();
}
public function drawMenuEntries($menu_entries) {
// Ensure that menu-entries are not empty.
if (empty($menu_entries) || !is_array($menu_entries)) { return;
}
foreach ($menu_entries as $menu_entry) {
// Check menu entry.
if (empty($menu_entry)) { continue;
}
if (!isset($menu_entry['menu_new_tab'])) { $menu_entry['menu_new_tab'] = false;
}
if (!isset($menu_entry['menu_url'])) { $menu_entry['menu_url'] = '/';
}
if (!isset($menu_entry['menu_login_status'])) { $menu_entry['menu_login_status'] = 0;
}
if (!isset($menu_entry['menu_link_text'])) { $menu_entry['menu_link_text'] = __('Link Text Missing', 'asgaros-forum');
}
// Check login status.
$login_status = is_user_logged_in();
$menu_login_status = $menu_entry['menu_login_status'];
if ($menu_login_status == 1 && ! $login_status) {
continue;
} else if ($menu_login_status == 2 && $login_status) {
continue;
}
// Check if menu-URL is a slug.
$menu_url = $menu_entry['menu_url'];
if ($menu_url[0] == '/') {
$menu_url = get_home_url().$menu_url;
}
// Check menu class.
$menu_class = (isset($menu_entry['menu_class'])) ? $menu_entry['menu_class'] : 'default-link';
// Check if link has to open in a new tab.
$new_tab = ($menu_entry['menu_new_tab']) ? '_blank' : '_self';
echo '<a class="'.esc_attr($menu_class).'" href="'.esc_url($menu_url).'" target="'.esc_attr($new_tab).'">'.esc_html($menu_entry['menu_link_text']).'</a>';
}
}
public function homeLink() {
$home_url = $this->get_link('home');
return array(
'menu_class' => 'home-link',
'menu_link_text' => esc_html__('Forum', 'asgaros-forum'),
'menu_url' => $home_url,
'menu_login_status' => 0,
'menu_new_tab' => false,
);
}
public function showLogoutLink() {
if ($this->options['show_logout_button']) {
$logout_url = wp_logout_url($this->get_link('current', false, false, '', false));
return array(
'menu_class' => 'logout-link',
'menu_link_text' => esc_html__('Logout', 'asgaros-forum'),
'menu_url' => $logout_url,
'menu_login_status' => 1,
'menu_new_tab' => false,
);
}
}
public function showLoginLink() {
if ($this->options['show_login_button']) {
$login_url = wp_login_url($this->get_link('current', false, false, '', false));
if (!empty($this->options['custom_url_login'])) {
$login_url = $this->options['custom_url_login'];
}
return array(
'menu_class' => 'login-link',
'menu_link_text' => esc_html__('Login', 'asgaros-forum'),
'menu_url' => $login_url,
'menu_login_status' => 2,
'menu_new_tab' => false,
);
}
}
public function showRegisterLink() {
if ( $this->options['show_register_button']) {
$register_url = wp_registration_url();
if (!empty($this->options['custom_url_register'])) {
$register_url = $this->options['custom_url_register'];
}
return array(
'menu_class' => 'register-link',
'menu_link_text' => esc_html__('Register', 'asgaros-forum'),
'menu_url' => $register_url,
'menu_login_status' => 2,
'menu_new_tab' => false,
);
}
}
public function delete_topic($topic_id, $admin_action = false, $permission_check = true) {
// Cancel when no topic is given.
if (!$topic_id) {
return false;
}
// Cancel when topic does not exist.
if (!$this->content->topic_exists($topic_id)) {
return false;
}
// Cancel if user cannot delete topic.
if ($permission_check) {
$user_id = get_current_user_id();
if (!$this->permissions->can_delete_topic($user_id, $topic_id)) {
return false;
}
}
// Continue ...
do_action('asgarosforum_before_delete_topic', $topic_id);
// Delete posts.
$posts = $this->db->get_col($this->db->prepare("SELECT id FROM {$this->tables->posts} WHERE parent_id = %d;", $topic_id));
foreach ($posts as $post) {
$this->remove_post($post, false);
}
// Delete topic.
$this->db->delete($this->tables->topics, array('id' => $topic_id), array('%d'));
$this->notifications->remove_all_topic_subscriptions($topic_id);
do_action('asgarosforum_after_delete_topic', $topic_id);
if (!$admin_action) {
wp_safe_redirect(html_entity_decode($this->get_link('forum', $this->current_forum)));
exit;
}
}
public function moveTopic() {
// Ensure forum-ID is set.
if (empty($_POST['newForumID'])) {
return;
}
$new_forum_id = sanitize_key($_POST['newForumID']);
if ($this->permissions->isModerator('current') && $new_forum_id && $this->content->forum_exists($new_forum_id)) {
$this->db->update($this->tables->topics, array('parent_id' => $new_forum_id), array('id' => $this->current_topic), array('%d'), array('%d'));
$this->db->update($this->tables->posts, array('forum_id' => $new_forum_id), array('parent_id' => $this->current_topic), array('%d'), array('%d'));
wp_safe_redirect(html_entity_decode($this->get_link('topic', $this->current_topic)));
exit;
}
}
public function remove_post($post_id, $permission_check = true) {
// Cancel if no post is given.
if (!$post_id) {
return false;
}
// Cancel if post does not exist.
if (!$this->content->post_exists($post_id)) {
return false;
}
// Cancel if user cannot delete post.
if ($permission_check) {
$user_id = get_current_user_id();
if (!$this->permissions->can_delete_post($user_id, $post_id)) {
return false;
}
}
// Delete post.
do_action('asgarosforum_before_delete_post', $post_id);
$this->uploads->delete_post_files($post_id);
$this->reports->remove_report($post_id, false);
$this->reactions->remove_all_reactions($post_id);
$this->db->delete($this->tables->posts, array('id' => $post_id), array('%d'));
do_action('asgarosforum_after_delete_post', $post_id);
}
public function change_status($property) {
$user_id = get_current_user_id();
if ($property == 'closed') {
if (!$this->permissions->can_close_topic($user_id, $this->current_topic)) {
return false;
}
$this->db->update($this->tables->topics, array('closed' => 1), array('id' => $this->current_topic), array('%d'), array('%d'));
} else if ($property == 'open') {
if (!$this->permissions->can_open_topic($user_id, $this->current_topic)) {
return false;
}
$this->db->update($this->tables->topics, array('closed' => 0), array('id' => $this->current_topic), array('%d'), array('%d'));
}
}
public function set_sticky($topic_id, $sticky_mode) {
// Ensure that the user is able to pin topics.
if (!$this->permissions->can_pin_topic(get_current_user_id(), $this->current_topic)) {
return;
}
// Ensure that only correct values can get set.
switch ($sticky_mode) {
case 0:
case 1:
case 2:
$this->db->update($this->tables->topics, array('sticky' => $sticky_mode), array('id' => $topic_id), array('%d'), array('%d'));
break;
}
}
public function is_topic_sticky($topic_id) {
$status = $this->db->get_var("SELECT sticky FROM {$this->tables->topics} WHERE id = {$topic_id};");
if ((int) $status > 0) {
return true;
} else {
return false;
}
}
private $is_topic_closed_cache = array();
public function is_topic_closed($topic_id) {
if (!isset($this->is_topic_closed_cache[$topic_id])) {
$status = $this->db->get_var("SELECT closed FROM {$this->tables->topics} WHERE id = {$topic_id};");
if ((int) $status === 1) {
$this->is_topic_closed_cache[$topic_id] = true;
} else {
$this->is_topic_closed_cache[$topic_id] = false;
}
}
return $this->is_topic_closed_cache[$topic_id];
}
// Returns TRUE if the forum is opened or the user has at least moderator rights.
public function forumIsOpen() {
if (!$this->permissions->isModerator('current')) {
$status = $this->db->get_var($this->db->prepare("SELECT forum_status FROM {$this->tables->forums} WHERE id = %d;", $this->current_forum));
if ($status == 'closed') {
return false;
}
}
return true;
}
// Builds and returns a requested link.
public function get_link($type, $elementID = false, $additionalParameters = false, $appendix = '', $escapeURL = true) {
return $this->rewrite->get_link($type, $elementID, $additionalParameters, $appendix, $escapeURL);
}
// Checks if an element exists and sets all parent IDs based on the given id and its content type.
public function setParents($id, $contentType) {
// Set possible error messages.
$error = array();
$error['post'] = __('Sorry, this post does not exist.', 'asgaros-forum');
$error['topic'] = __('Sorry, this topic does not exist.', 'asgaros-forum');
$error['forum'] = __('Sorry, this forum does not exist.', 'asgaros-forum');
if ($id) {
$query = '';
$results = false;
// Build the query.
switch ($contentType) {
case 'post':
$query = "SELECT f.parent_id AS current_category, f.id AS current_forum, f.name AS current_forum_name, f.parent_forum AS parent_forum, pf.name AS parent_forum_name, t.id AS current_topic, t.name AS current_topic_name, p.id AS current_post, p.text AS current_description FROM {$this->tables->forums} AS f LEFT JOIN {$this->tables->forums} AS pf ON (pf.id = f.parent_forum) LEFT JOIN {$this->tables->topics} AS t ON (f.id = t.parent_id) LEFT JOIN {$this->tables->posts} AS p ON (t.id = p.parent_id) WHERE p.id = {$id};";
break;
case 'topic':
$query = "SELECT f.parent_id AS current_category, f.id AS current_forum, f.name AS current_forum_name, f.parent_forum AS parent_forum, pf.name AS parent_forum_name, t.id AS current_topic, t.name AS current_topic_name, (SELECT td.text FROM {$this->tables->posts} AS td WHERE td.parent_id = t.id ORDER BY td.id ASC LIMIT 1) AS current_description FROM {$this->tables->forums} AS f LEFT JOIN {$this->tables->forums} AS pf ON (pf.id = f.parent_forum) LEFT JOIN {$this->tables->topics} AS t ON (f.id = t.parent_id) WHERE t.id = {$id};";
break;
case 'forum':
$query = "SELECT f.parent_id AS current_category, f.id AS current_forum, f.name AS current_forum_name, f.parent_forum AS parent_forum, pf.name AS parent_forum_name, f.description AS current_description FROM {$this->tables->forums} AS f LEFT JOIN {$this->tables->forums} AS pf ON (pf.id = f.parent_forum) WHERE f.id = {$id};";
break;
}
$results = $this->db->get_row($query);
// When the element exists, set parents and exit function.
if ($results) {
if ($contentType === 'post' || $contentType === 'topic' || $contentType === 'forum') {
// Generate description.
$description = $results->current_description;
$description = wp_strip_all_tags($description);
$description = esc_html($description);
$description = str_replace(array("\r", "\n"), '', $description);
$this->current_description = $this->cut_string($description, 155, true);
$this->current_category = $results->current_category;
$this->parent_forum = $results->parent_forum;
$this->parent_forum_name = $results->parent_forum_name;
$this->current_forum = $results->current_forum;
$this->current_forum_name = $results->current_forum_name;
}
$this->current_topic = ($contentType === 'post' || $contentType === 'topic') ? $results->current_topic : false;
$this->current_topic_name = ($contentType === 'post' || $contentType === 'topic') ? $results->current_topic_name : false;
$this->current_post = ($contentType === 'post') ? $results->current_post : false;
$this->parents_set = true;
return;
}
}
// Assign error message, because when this location is reached, no parents has been set.
$this->error = $error[$contentType];
}
// Returns the amount of users.
public function count_users() {
return $this->db->get_var("SELECT COUNT(u.ID) FROM {$this->db->users} u");
}
// Prevents oembed dataparsing for links which points to the own forum.
public function prevent_oembed_dataparse($returnString, $data, $url) {
$url_check = strpos($url, $this->rewrite->get_link('home'));
if ($url_check !== false) {
return $url;
}
return $returnString;
}
public function create_file($path, $content) {
// Create binding for the file first.
$binding = @fopen($path, 'wb');
// Check if the binding could get created.
if ($binding) {
// Write the content to the file.
$writing = @fwrite($binding, $content);
// Close the file.
fclose($binding);
// Clear stat cache so we can set the correct permissions.
clearstatcache();
// Get information about the file.
$file_stats = @stat(dirname($path));
// Update the permissions of the file.
$file_permissions = $file_stats['mode'] & 0007777;
$file_permissions = $file_permissions & 0000666;
@chmod($path, $file_permissions);
// Clear stat cache again so PHP is aware of the new permissions.
clearstatcache();
return true;
}
return false;
}
public function read_file($path) {
// Create binding for the file first.
$binding = @fopen($path, 'r');
// Check if the binding could get created.
if ($binding) {
// Ensure that the file is not empty.
$file_size = @filesize($path);
if (isset($file_size) && $file_size > 0) {
// Read the complete file.
$file_data = fread($binding, $file_size);
// Close the file.
fclose($binding);
// Return the file data.
return $file_data;
}
}
return false;
}
public function delete_file($path) {
if (file_exists($path)) {
wp_delete_file($path);
}
}
public function delete_user_form_reassign($current_user, $userids) {
// Remove own ID from users which should get deleted.
$userids = array_diff($userids, array($current_user->ID));
// Cancel if there are no users to delete.
if (empty($userids)) {
return;
}
// Check if users have posts or topics.
$users_have_content = false;
if ($this->db->get_var("SELECT ID FROM {$this->tables->posts} WHERE author_id IN(".implode(',', $userids).') LIMIT 1;')) {
$users_have_content = true;
}
if ($this->db->get_var("SELECT ID FROM {$this->tables->topics} WHERE author_id IN(".implode(',', $userids).') LIMIT 1;')) {
$users_have_content = true;
}
// Cancel if users have no posts.
if ($users_have_content === false) {
return;
}
// Show reassign-options.
echo '<h2>'.esc_html__('Forum', 'asgaros-forum').'</h2>';
echo '<fieldset>';
echo '<p><legend>';
// Count users to delete.
$go_delete = count($userids);
if ($go_delete === 1) {
echo esc_html__('What should be done with forum posts owned by this user?', 'asgaros-forum');
} else {
echo esc_html__('What should be done with forum posts owned by these users?', 'asgaros-forum');
}
echo '</legend></p>';
echo '<ul style="list-style: none;">';
// No reassign
echo '<li><input type="radio" id="forum_reassign0" name="forum_reassign" value="no" checked="checked">';
echo '<label for="forum_reassign0">'.esc_html__('Do not reassign forum posts.', 'asgaros-forum').'</label></li>';
// Reassign
echo '<li><input type="radio" id="forum_reassign1" name="forum_reassign" value="yes">';
echo '<label for="forum_reassign1">'.esc_html__('Reassign all forum posts to:', 'asgaros-forum').'</label> ';
wp_dropdown_users(array(
'name' => 'forum_reassign_user',
'exclude' => $userids,
));
echo '</li>';
// Delete
echo '<li><input type="radio" id="forum_reassign2" name="forum_reassign" value="delete">';
echo '<label for="forum_reassign2">'.esc_html__('Delete all forum posts and topics owned by this user.', 'asgaros-forum').'</label></li>';
echo '</ul></fieldset>';
}
public function deleted_user_reassign($id, $reassign) {
// Ensure that correct values are passed.
if (empty($_POST['forum_reassign'])) {
return;
}
if (!in_array($_POST['forum_reassign'], array('no', 'yes', 'delete'))) {
return;
}
// Reassign forum posts and topics.
if ($_POST['forum_reassign'] == 'yes') {
if (empty($_POST['forum_reassign_user'])) {
return;
}
$author_id = sanitize_key($_POST['forum_reassign_user']);
$this->db->update($this->tables->posts, array('author_id' => $author_id), array('author_id' => $id), array('%d'), array('%d'));
$this->db->update($this->tables->topics, array('author_id' => $author_id), array('author_id' => $id), array('%d'), array('%d'));
}
// Delete forum posts and topics.
if ($_POST['forum_reassign'] == 'delete') {
// First delete topics ...
$topics = $this->db->get_col("SELECT id FROM {$this->tables->topics} WHERE author_id = {$id};");
if (!empty($topics)) {
foreach ($topics as $topic) {
$this->delete_topic($topic, true, false);
}
}
// Then delete posts ...
$posts = $this->db->get_col("SELECT id FROM {$this->tables->posts} WHERE author_id = {$id};");
if (!empty($posts)) {
foreach ($posts as $post) {
$this->remove_post($post, false);
}
}
}
}
// Extract the first URL of an image from a given string.
public function extract_image_url($content) {
$images = array();
// Check if content is given.
if ($content) {
// Try to find images.
preg_match_all('#https?://[^\s\'\"<>]+\.(?:jpg|jpeg|png|gif)#isu', $content, $found, PREG_SET_ORDER);
if (empty($found)) {
preg_match_all('#//[^\s\'\"<>]+\.(?:jpg|jpeg|png|gif)#isu', $content, $found, PREG_SET_ORDER);
}
if (empty($found)) {
preg_match_all('#https?://[^\s\'\"<>]+#isu', $content, $found, PREG_SET_ORDER);
}
if (empty($found)) {
preg_match_all('#//[^\s\'\"<>]+#isu', $content, $found, PREG_SET_ORDER);
}
// If images found, check extensions.
if (!empty($found)) {
foreach ($found as $match) {
$extension = pathinfo($match[0], PATHINFO_EXTENSION);
if ($extension) {
$check = false;
$extension = strtolower($extension);
if ($extension == 'jpg' || $extension == 'jpeg' || $extension == 'png' || $extension == 'gif') {
$check = true;
}
if ($check) {
$images[] = $match[0];
break;
}
}
}
}
}
if (empty($images)) {
return false;
} else {
return $images[0];
}
}
// Tries to get the signature for a given user.
public function get_signature($user_id) {
// Ensure signatures are enabled.
if (!$this->options['allow_signatures']) {
return false;
}
// Ensure that the user has the permission to use a signature.
if (!$this->permissions->can_use_signature($user_id)) {
return false;
}
// Try to get signature.
$signature = get_user_meta($user_id, 'asgarosforum_signature', true);
// Prepare signature based on settings.
if ($this->options['signatures_html_allowed']) {
$signature = strip_tags($signature, $this->options['signatures_html_tags']);
} else {
$signature = esc_html(wp_strip_all_tags($signature));
}
// Trim it.
$signature = trim($signature);
// Allow filtering the signature.
$signature = apply_filters('asgarosforum_signature', $signature);
// Ensure signature is not empty.
if (empty($signature)) {
return false;
}
return $signature;
}
public function render_reputation_badges($number) {
if ($this->options['enable_reputation']) {
echo '<span class="reputation-badges">';
if ($number < $this->options['reputation_level_1_posts']) {
echo '<i class="far fa-star-half"></i>';
} else {
echo '<i class="fas fa-star"></i>';
// Add an additional star for every remaining level.
for ($i = 2; $i <= 5; $i++) {
if ($number >= $this->options['reputation_level_'.$i.'_posts']) {
echo '<i class="fas fa-star"></i>';
} else {
break;
}
}
}
echo '</span>';
}
}
/*******************************************/
/* Functions for automatic topic creation. */
/*******************************************/
public function post_transition_update($new_status, $old_status, $post) {
// Ensure that the required option is activated.
if ($this->options['create_blog_topics_id'] == 0) {
return;
}
if ($post->post_type == 'post' && $new_status == 'publish' && $old_status != 'publish') {
$forum_id = $this->options['create_blog_topics_id'];
$this->create_blog_topic($forum_id, $post);
}
}
public function create_blog_topic($forum_id, $post_object) {
if ($this->content->forum_exists($forum_id)) {
// Prepare title and content
$post_title = apply_filters('asgarosforum_filter_automatic_topic_title', $post_object->post_title, $post_object);
$post_content = apply_filters('asgarosforum_filter_automatic_topic_content', $post_object->post_content, $post_object);
// Create the new topic
$ids = $this->content->insert_topic($forum_id, $post_title, $post_content, $post_object->post_author);
if ($this->approval->is_topic_approved($ids->topic_id)) {
// Send notifications about new topic.
$this->notifications->notify_about_new_topic($ids->topic_id);
} else {
// Notify siteowner about new unapproved topic.
$this->approval->notify_about_new_unapproved_topic($ids->topic_id);
}
}
}
public function add_topic_meta_box_setup() {
add_action('add_meta_boxes', array($this, 'add_topic_meta_box'), 10, 2);
add_action('save_post', array($this, 'process_topic_meta_box'), 10, 2);
}
public function add_topic_meta_box($post_type, $post) {
if (!current_user_can('publish_post', $post->ID)) {
return;
}
$post_types = apply_filters('asgarosforum_filter_meta_post_type', array('post', 'page'));
add_meta_box(
'asgaros-forum-topic-meta-box',
__('Create Forum Topic', 'asgaros-forum'),
array($this, 'add_topic_meta_box_content'),
$post_types,
'side',
'low'
);
}
public function add_topic_meta_box_content($post) {
echo '<select name="add_topic_in_forum" id="add_topic_in_forum">';
echo '<option value="0"></option>';
// Generate list of available forums.
$categories = $this->content->get_categories(false);
if ($categories) {
foreach ($categories as $category) {
$forums = $this->get_forums($category->term_id, 0);
if ($forums) {
foreach ($forums as $forum) {
echo '<option value="'.esc_attr($forum->id).'">'.esc_html($forum->name).'</option>';
if ($forum->count_subforums > 0) {
$subforums = $this->get_forums($category->term_id, $forum->id);
foreach ($subforums as $subforum) {
echo '<option value="'.esc_attr($subforum->id).'">--- '.esc_html($subforum->name).'</option>';
}
}
}
}
}
}
echo '</select>';
echo '<br>';
echo '<label for="add_topic_in_forum">'.esc_html__('A topic is created in the selected forum when you save this document.', 'asgaros-forum').'</label>';
}
public function process_topic_meta_box($post_id, $post) {
if (!current_user_can('publish_post', $post_id)) {
return;
}
$forum_id = !empty($_POST['add_topic_in_forum']) ? sanitize_key($_POST['add_topic_in_forum']) : 0;
if ($forum_id > 0) {
$this->create_blog_topic($forum_id, $post);
}
}
public function has_error() {
if (!empty($this->error)) {
return true;
}
return false;
}
public function render_error() {
echo '<div class="error">';
echo wp_kses_post($this->error);
echo '</div>';
}
}