/** * Get an array of user IDs for users who are subscribed to the forum. * * @since 1.0.0 * @access public * @param int $forum_id * @return array */ function mb_get_forum_subscribers($forum_id = 0) { $forum_id = mb_get_forum_id($forum_id); $users = wp_cache_get('mb_get_forum_subscribers_' . $forum_id, 'message-board-users'); if (false === $users) { global $wpdb; $users = $wpdb->get_col($wpdb->prepare("SELECT user_id FROM {$wpdb->usermeta} WHERE meta_key = %s AND FIND_IN_SET( '{$forum_id}', meta_value ) > 0", mb_get_user_forum_subscriptions_meta_key())); wp_cache_set('mb_get_forum_subscribers_' . $forum_id, $users, 'message-board-users'); } return apply_filters('mb_get_forum_subscribers', $users); }
/** * Function for inserting topic data when it's first published. * * @since 1.0.0 * @access public * @param object $post * @return void */ function mb_insert_topic_data($post) { /* Hook for before inserting topic data. */ do_action('mb_before_insert_topic_data', $post); /* Get the topic ID. */ $topic_id = mb_get_topic_id($post->ID); /* Get the forum ID. */ $forum_id = mb_get_forum_id($post->post_parent); /* Get the User ID. */ $user_id = mb_get_user_id($post->post_author); /* Get the post date. */ $post_date = $post->post_date; $post_epoch = mysql2date('U', $post_date); /* Update user meta. */ $topic_count = mb_get_user_topic_count($user_id); update_user_meta($user_id, mb_get_user_topic_count_meta_key(), $topic_count + 1); /* Add topic meta. */ mb_set_topic_activity_datetime($topic_id, $post_date); mb_set_topic_activity_epoch($topic_id, $post_epoch); mb_set_topic_voices($topic_id, $user_id); mb_set_topic_voice_count($topic_id, 1); mb_set_topic_reply_count($topic_id, 0); /* If we have a forum ID. */ if (0 < $forum_id) { $topic_count = mb_get_forum_topic_count($forum_id); /* Update forum meta. */ mb_set_forum_activity_datetime($forum_id, $post_date); mb_set_forum_activity_epoch($forum_id, $post_epoch); mb_set_forum_last_topic_id($forum_id, $topic_id); mb_set_forum_topic_count($forum_id, absint($topic_count) + 1); } /* Notify subscribers that there's a new topic. */ mb_notify_subscribers($post); /* Hook for after inserting topic data. */ do_action('mb_after_insert_topic_data', $post); }
/** * Overwrites capabilities in certain scenarios. * * @since 1.0.0 * @access public * @param array $caps * @param string $cap * @param int $user_id * @param array $args * @return array */ function mb_forum_map_meta_cap($caps, $cap, $user_id, $args) { /* Checks if a user can read a specific forum. */ if ('read_post' === $cap && mb_is_forum($args[0])) { $post = get_post($args[0]); if ($user_id != $post->post_author) { $parent_id = $post->post_parent; /* If we have a parent forum and the user can't read it, don't allow reading this forum. */ if (0 < $parent_id && !mb_user_can($user_id, 'read_forum', $parent_id)) { $caps = array('do_not_allow'); /* If the user can read the parent forum, check if they can read this one. */ } else { $post_type = get_post_type_object($post->post_type); $post_status = mb_get_forum_status($post->ID); $status_obj = get_post_status_object($post_status); if (mb_get_hidden_post_status() === $status_obj->name) { $caps[] = $post_type->cap->read_hidden_forums; } elseif (mb_get_private_post_status() === $status_obj->name) { $caps[] = $post_type->cap->read_private_posts; } elseif ($post_type->cap->read !== $post_type->cap->read_others_forums) { $caps[] = $post_type->cap->read_others_forums; } else { $caps = array(); } } } else { $caps = array(); } /* Meta cap for editing a single forum. */ } elseif ('edit_post' === $cap && mb_is_forum($args[0])) { $post = get_post($args[0]); $forum_obj = get_post_type_object(mb_get_forum_post_type()); if ($user_id != $post->post_author) { // Open forums. if (mb_is_forum_open($args[0])) { $caps[] = $forum_obj->cap->edit_open_forums; } elseif (mb_is_forum_closed($args[0])) { $caps[] = $forum_obj->cap->edit_closed_forums; } elseif (mb_is_forum_hidden($args[0])) { $caps[] = $forum_obj->cap->edit_hidden_forums; } } /* Meta cap for opening a single forum. */ } elseif ('open_forum' === $cap) { $caps = array(); $caps[] = user_can($user_id, 'edit_forum', $args[0]) ? 'open_forums' : 'do_not_allow'; /* Meta cap for closing a single forum. */ } elseif ('close_forum' === $cap) { $caps = array(); $caps[] = user_can($user_id, 'edit_forum', $args[0]) ? 'close_forums' : 'do_not_allow'; /* Meta cap for privatizing a single forum. */ } elseif ('privatize_forum' === $cap) { $caps = array(); $caps[] = user_can($user_id, 'edit_forum', $args[0]) ? 'privatize_forums' : 'do_not_allow'; /* Meta cap for hiding a single forum. */ } elseif ('hide_forum' === $cap) { $caps = array(); $caps[] = user_can($user_id, 'edit_forum', $args[0]) ? 'hide_forums' : 'do_not_allow'; /* Meta cap for spamming a single forum. */ } elseif ('archive_forum' === $cap) { $caps = array(); $caps[] = user_can($user_id, 'edit_forum', $args[0]) ? 'archive_forums' : 'do_not_allow'; /* Meta cap for deleting a specific forum. */ } elseif ('delete_post' === $cap && mb_is_forum($args[0])) { $forum_id = mb_get_forum_id($args[0]); if (mb_get_default_forum_id() === $forum_id) { $caps = array('do_not_allow'); } /* Meta cap check for accessing the forum form. */ } elseif ('access_forum_form' === $cap) { $caps = array('create_forums'); /* If this is a single forum page, check if user can create sub-forums. */ if (mb_is_single_forum()) { $forum_id = mb_get_forum_id(); if (!current_user_can('read_forum', $forum_id)) { $caps[] = 'do_not_allow'; } elseif (!mb_forum_allows_subforums($forum_id)) { $caps[] = 'do_not_allow'; } } elseif (mb_is_forum_edit() && !user_can($user_id, 'edit_post', mb_get_forum_id())) { $caps[] = 'do_not_allow'; } } return $caps; }
_e('Order:', 'message-board'); ?> </label> <input type="number" id="mb_menu_order" name="mb_menu_order" value="<?php echo esc_attr(mb_get_forum_order()); ?> " /> </p> <p> <label for="mb_forum_content"><?php _e('Description:', 'message-board'); ?> </label> <textarea id="mb_forum_content" name="mb_forum_content"><?php echo format_to_edit(mb_code_trick_reverse(mb_get_forum_content(mb_get_forum_id(), 'raw'))); ?> </textarea> </p> <p> <input type="submit" value="<?php esc_attr_e('Submit', 'message-board'); ?> " /> </p> <?php /* <p> <label>
/** * Displays admin notices for the edit forum screen. * * @since 1.0.0 * @access public * @return void */ public function admin_notices() { $allowed_notices = array(mb_get_open_post_status(), mb_get_close_post_status(), mb_get_archive_post_status()); /* If we have an allowed notice. */ if (isset($_GET['mb_forum_notice']) && in_array($_GET['mb_forum_notice'], $allowed_notices) && isset($_GET['forum_id'])) { $notice = $_GET['mb_forum_notice']; $forum_id = mb_get_forum_id(absint($_GET['forum_id'])); if (mb_get_close_post_status() === $notice) { $text = sprintf(__('The forum "%s" was successfully closed.', 'message-board'), mb_get_forum_title($forum_id)); } elseif (mb_get_open_post_status() === $notice) { $text = sprintf(__('The forum "%s" was successfully opened.', 'message-board'), mb_get_forum_title($forum_id)); } elseif (mb_get_archive_post_status() === $notice) { $text = sprintf(__('The forum "%s" was successfully archived.', 'message-board'), mb_get_forum_title($forum_id)); } if (!empty($text)) { printf('<div class="updated"><p>%s</p></div>', $text); } } }
/** * Overwrites capabilities in certain scenarios. * * @since 1.0.0 * @access public * @param array $caps * @param string $cap * @param int $user_id * @param array $args * @return array */ function mb_topic_map_meta_cap($caps, $cap, $user_id, $args) { /* Checks if a user can read a specific topic. */ if ('read_post' === $cap && mb_is_topic($args[0])) { $post = get_post($args[0]); /* Only run our code if the user isn't the post author. */ if ($user_id != $post->post_author) { $forum_id = $post->post_parent; /* If we have a forum and the user can't read it, don't allow reading the topic. */ if (0 < $forum_id && !mb_user_can($user_id, 'read_forum', $forum_id)) { $caps = array('do_not_allow'); /* If the user can read the forum, check if they can read the topic. */ } else { $post_type = get_post_type_object($post->post_type); $post_status = mb_get_topic_status($post->ID); $status_obj = get_post_status_object($post_status); if (mb_get_hidden_post_status() === $status_obj->name) { $caps[] = $post_type->cap->read_hidden_topics; } elseif (mb_get_private_post_status() === $status_obj->name) { $caps[] = $post_type->cap->read_private_posts; } elseif ($post_type->cap->read !== $post_type->cap->read_others_topics) { $caps[] = $post_type->cap->read_others_topics; } else { $caps = array(); } //$caps[] = $post_type->cap->read; } } else { $caps = array(); } /* Meta cap for editing a single topic. */ } elseif ('edit_post' === $cap && mb_is_topic($args[0])) { $post = get_post($args[0]); $topic_obj = get_post_type_object(mb_get_topic_post_type()); if ($user_id != $post->post_author) { // Open topics. if (mb_is_topic_open($args[0])) { $caps[] = $topic_obj->cap->edit_open_topics; } elseif (mb_is_topic_closed($args[0])) { $caps[] = $topic_obj->cap->edit_closed_topics; } elseif (mb_is_topic_hidden($args[0])) { $caps[] = $topic_obj->cap->edit_hidden_topics; } } // Spam topics if (mb_is_topic_spam($args[0])) { $caps[] = $topic_obj->cap->edit_spam_topics; } elseif (mb_is_topic_orphan($args[0])) { $caps[] = $topic_obj->cap->edit_orphan_topics; } /* Meta cap for opening a single topic. */ } elseif ('open_topic' === $cap) { $caps = array(); $caps[] = user_can($user_id, 'edit_topic', $args[0]) ? 'open_topics' : 'do_not_allow'; /* Meta cap for closing a single topic. */ } elseif ('close_topic' === $cap) { $caps = array(); $caps[] = user_can($user_id, 'edit_topic', $args[0]) ? 'close_topics' : 'do_not_allow'; /* Meta cap for privatizing a single topic. */ } elseif ('privatize_topic' === $cap) { $caps = array(); $caps[] = user_can($user_id, 'edit_topic', $args[0]) ? 'privatize_topics' : 'do_not_allow'; /* Meta cap for hiding a single topic. */ } elseif ('hide_topic' === $cap) { $caps = array(); $caps[] = user_can($user_id, 'edit_topic', $args[0]) ? 'hide_topics' : 'do_not_allow'; /* Meta cap for spamming a single topic. */ } elseif ('spam_topic' === $cap) { $caps = array(); $caps[] = user_can($user_id, 'edit_topic', $args[0]) ? 'spam_topics' : 'do_not_allow'; /* Meta cap for spamming a single topic. */ } elseif ('super_topic' === $cap) { $caps = array(); $caps[] = user_can($user_id, 'edit_topic', $args[0]) ? 'super_topics' : 'do_not_allow'; /* Meta cap for spamming a single topic. */ } elseif ('stick_topic' === $cap) { $caps = array(); $caps[] = user_can($user_id, 'edit_topic', $args[0]) ? 'stick_topics' : 'do_not_allow'; /* Meta cap check for accessing the topic form. */ } elseif ('access_topic_form' === $cap) { $caps = array('create_topics'); if (mb_is_single_forum()) { $forum_id = mb_get_forum_id(); if (!current_user_can('read_forum', $forum_id)) { $caps[] = 'do_not_allow'; } elseif (!mb_forum_allows_topics($forum_id)) { $caps[] = 'do_not_allow'; } } elseif (mb_is_topic_edit() && !user_can($user_id, 'edit_post', mb_get_topic_id())) { $caps[] = 'do_not_allow'; } } return $caps; }
/** * Callback function on the `after_delete_post` hook for when a forum is deleted. * * @todo All forum topics need to become orphans at this point. Attempt to move topics into parent if avail. * @todo Reset counts for parent forums. * @todo `wp_die()` if this is the default forum. * * @since 1.0.0 * @access public * @param int $post_id * @return void */ function mb_after_delete_forum($post_id) { global $wpdb; $mb = message_board(); if (is_object($mb->deleted_post) && $mb->deleted_post->ID === $post_id) { $forum_id = mb_get_forum_id($post_id); $user_id = mb_get_user_id($post->deleted_post->post_author); $parent_forum_id = $mb->deleted_post->post_parent; /* Get the current forum's subforum IDs. */ $subforum_ids = $wpdb->get_col($wpdb->prepare("SELECT ID FROM {$wpdb->posts} WHERE post_type = %s AND post_parent = %s ORDER BY menu_order DESC", mb_get_forum_post_type(), absint($forum_id))); if (!empty($subforum_ids)) { $moved_forums = false; while (0 < $parent_forum_id) { if (mb_forum_allows_subforums($parent_forum_id)) { /* Change all of the subforums' parents to the new forum ID. */ $wpdb->query($wpdb->prepare("UPDATE {$wpdb->posts} SET post_parent = %d WHERE ID IN (" . implode(',', $subforum_ids) . ")", absint($parent_forum_id))); /* Reset data based on new forum. */ mb_reset_forum_data($parent_forum_id); $parent_forum_id = 0; $moved_forums = true; /* Break out of the while loop at this point. */ break; } $post = get_post($parent_forum_id); $parent_forum_id = $post->post_parent; } /* If subforums didn't get moved to a new forum, make them a top-level forum. */ if (false === $moved_forums) { $wpdb->query($wpdb->prepare("UPDATE {$wpdb->posts} SET post_parent = %d WHERE ID IN (" . implode(',', $subforum_ids) . ")", 0)); } } $parent_forum_id = $mb->deleted_post->post_parent; /* Get the current forum's topic IDs. */ $topic_ids = $wpdb->get_col($wpdb->prepare("SELECT ID FROM {$wpdb->posts} WHERE post_type = %s AND post_parent = %s ORDER BY menu_order DESC", mb_get_topic_post_type(), absint($forum_id))); if (!empty($topic_ids)) { $moved_topics = false; while (0 < $parent_forum_id) { if (mb_forum_allows_topics($parent_forum_id)) { /* Change all of the topics' parents to the new forum ID. */ $wpdb->query($wpdb->prepare("UPDATE {$wpdb->posts} SET post_parent = %d WHERE ID IN (" . implode(',', $topic_ids) . ")", absint($parent_forum_id))); /* Reset data based on new forum. */ mb_reset_forum_data($parent_forum_id); $parent_forum_id = 0; $moved_topics = true; /* Break out of the while loop at this point. */ break; } $post = get_post($parent_forum_id); $parent_forum_id = $post->post_parent; } /* If topics didn't get moved to a new forum, set their status to "orphan". */ if (false === $moved_topics) { $wpdb->query($wpdb->prepare("UPDATE {$wpdb->posts} SET post_status = %s WHERE ID IN (" . implode(',', $topic_ids) . ")", mb_get_orphan_post_status())); } } /* Reset user forum count. */ mb_set_user_forum_count($user_id); } }
/** * Returns the forum type for a specific forum. * * @since 1.0.0 * @access public * @param int $forum_id * @return string */ function mb_get_forum_type($forum_id = 0) { $forum_id = mb_get_forum_id($forum_id); $forum_type = $forum_id ? get_post_meta($forum_id, mb_get_forum_type_meta_key(), true) : ''; $forum_type = !empty($forum_type) && mb_forum_type_exists($forum_type) ? $forum_type : mb_get_normal_forum_type(); return apply_filters('mb_get_forum_type', $forum_type, $forum_id); }
<?php mb_forum_toggle_open_link(); ?> <?php mb_forum_toggle_close_link(); ?> <?php mb_forum_toggle_trash_link(); ?> </p> </header><!-- .mb-page-header --> <?php if (current_user_can('read_forum', mb_get_forum_id())) { // Check if the current user can read the forum. ?> <?php mb_get_template_part('loop-forum', mb_show_hierarchical_forums() ? 'hierarchical' : 'flat'); ?> <?php if (mb_forum_type_allows_topics(mb_get_forum_type())) { // Only show topics if they're allowed. ?> <?php mb_get_template_part('loop', 'topic'); ?>
/** * Resets the forum's "latest" data. * * @since 1.0.0 * @access public * @param int $forum_id * @return int */ function mb_reset_forum_latest($forum_id) { global $wpdb; $forum_id = mb_get_forum_id($forum_id); $open_status = mb_get_open_post_status(); $close_status = mb_get_close_post_status(); $publish_status = mb_get_publish_post_status(); $private_status = mb_get_private_post_status(); $hidden_status = mb_get_hidden_post_status(); $status_where = "AND (post_status = '{$open_status}' OR post_status = '{$close_status}' OR post_status = '{$publish_status}' OR post_status = '{$private_status}' OR post_status = '{$hidden_status}')"; $topic_id = $wpdb->get_var($wpdb->prepare("SELECT ID FROM {$wpdb->posts} WHERE post_type = %s {$status_where} AND post_parent = %d ORDER BY menu_order DESC", mb_get_topic_post_type(), $forum_id)); if (!empty($topic_id)) { $t_status_where = "AND (topic.post_status = '{$open_status}' OR topic.post_status = '{$close_status}' OR topic.post_status = '{$publish_status}' OR topic.post_status = '{$private_status}' OR topic.post_status = '{$hidden_status}')"; $r_status_where = "AND reply.post_status = '{$publish_status}'"; $status_where = $t_status_where . $r_status_where; $reply_id = $wpdb->get_var($wpdb->prepare("SELECT reply.ID FROM {$wpdb->posts} AS reply INNER JOIN {$wpdb->posts} AS topic ON reply.post_parent = topic.ID WHERE topic.post_parent = %d {$status_where} ORDER BY reply.post_date DESC", $forum_id)); if ($reply_id) { mb_set_forum_last_reply_id($forum_id, $reply_id); mb_set_forum_last_topic_id($forum_id, $topic_id); $last_date = get_post($reply_id)->post_date; $epoch_date = mysql2date('U', $last_date); mb_set_forum_activity_datetime($forum_id, $last_date); mb_set_forum_activity_epoch($forum_id, $epoch_date); } else { delete_post_meta($forum_id, mb_get_forum_last_reply_id_meta_key()); mb_set_forum_last_topic_id($forum_id, $topic_id); $last_date = get_post($topic_id)->post_date; $epoch_date = mysql2date('U', $last_date); mb_set_forum_activity_datetime($forum_id, $last_date); mb_set_forum_activity_epoch($forum_id, $epoch_date); } } else { delete_post_meta($forum_id, mb_get_forum_last_reply_id_meta_key()); delete_post_meta($forum_id, mb_get_forum_last_topic_id_meta_key()); delete_post_meta($forum_id, mb_get_forum_activity_datetime_meta_key()); delete_post_meta($forum_id, mb_get_forum_activity_datetime_epoch_meta_key()); } }
/** * Filter on the `request` hook to change what posts are loaded. * * @since 1.0.0 * @access public * @param array $vars * @return array */ public function request($vars) { $new_vars = array(); /* Load topics of a specific forum. */ if (isset($_GET['post_parent'])) { $new_vars['post_parent'] = mb_get_forum_id($_GET['post_parent']); } elseif (isset($_GET['topic_type']) && mb_topic_type_exists($_GET['topic_type'])) { $new_vars['meta_key'] = mb_get_topic_type_meta_key(); $new_vars['meta_value'] = sanitize_key($_GET['topic_type']); } elseif (isset($vars['orderby']) && 'post_parent' === $vars['orderby']) { $new_vars['orderby'] = 'post_parent'; } elseif (isset($vars['orderby']) && 'reply_count' === $vars['orderby']) { $new_vars['orderby'] = 'meta_value_num'; $new_vars['meta_key'] = mb_get_topic_reply_count_meta_key(); } elseif (isset($vars['orderby']) && 'voice_count' === $vars['orderby']) { $new_vars['orderby'] = 'meta_value_num'; $new_vars['meta_key'] = mb_get_topic_voice_count_meta_key(); } elseif (isset($vars['orderby']) && 'post_author' === $vars['orderby']) { $new_vars['orderby'] = 'post_author'; } /* Return the vars, merging with the new ones. */ return array_merge($vars, $new_vars); }
function mb_handler_forum_toggle_trash() { if (!isset($_GET['action']) || 'mb_toggle_trash' !== $_GET['action'] || !isset($_GET['forum_id'])) { return; } $forum_id = mb_get_forum_id($_GET['forum_id']); /* Verify nonce. */ if (!isset($_GET['mb_nonce']) || !wp_verify_nonce($_GET['mb_nonce'], "trash_forum_{$forum_id}")) { return; } if (!current_user_can('delete_forum', $forum_id)) { return; } $updated = mb_is_forum_trash($forum_id) ? wp_untrash_post($forum_id) : wp_trash_post($forum_id); $redirect = remove_query_arg(array('action', 'forum_id', 'mb_nonce')); wp_safe_redirect(esc_url($redirect)); }
/** * Filter on the `request` hook to change what posts are loaded. * * @since 1.0.0 * @access public * @param array $vars * @return array */ public function request($vars) { $new_vars = array(); /* Load replies of a specific topic. */ if (isset($_GET['post_parent'])) { $new_vars['post_parent'] = mb_get_topic_id($_GET['post_parent']); } elseif (isset($_GET['mb_forum'])) { $topic_ids = mb_get_forum_topic_ids(mb_get_forum_id($_GET['mb_forum'])); $new_vars['post_parent__in'] = (array) $topic_ids; } elseif (isset($vars['orderby']) && 'forum' === $vars['orderby']) { // @todo - Fix or remove //$new_vars['orderby'] = 'meta_value_num'; //$new_vars['meta_key'] = mb_get_reply_forum_id_meta_key(); } elseif (isset($vars['orderby']) && 'post_parent' === $vars['orderby']) { $new_vars['orderby'] = 'post_parent'; } elseif (isset($vars['orderby']) && 'post_author' === $vars['orderby']) { $new_vars['orderby'] = 'post_author'; } /* Return the vars, merging with the new ones. */ return array_merge($vars, $new_vars); }
/** * Topic content editor. * * @since 1.0.0 * @access public * @return void */ function mb_forum_editor() { add_action('wp_enqueue_editor', 'mb_dequeue_editor_scripts'); add_filter('the_editor', 'mb_forum_the_editor_filter'); wp_editor(format_to_edit(mb_code_trick_reverse(mb_get_forum_content(mb_get_forum_id(), 'raw'))), 'mb_forum_content', array('quicktags' => false, 'tinymce' => false, 'media_buttons' => false, 'editor_height' => 150)); }
/** * Conditional check to see if a topic allows new replies to be created. * * @since 1.0.0 * @access public * @param int $topic * @return bool */ function mb_topic_allows_replies($topic_id = 0) { $topic_id = mb_get_forum_id($topic_id); $forum_id = mb_get_topic_forum_id($topic_id); $allow = true; /* Check if the topic type allows replies. */ if (!mb_topic_type_allows_replies(mb_get_topic_type($topic_id))) { $allow = false; } elseif (!mb_topic_status_allows_replies(mb_get_topic_status($topic_id))) { $allow = false; } elseif (0 < $forum_id && !mb_forum_allows_topics($forum_id)) { $allow = false; } return apply_filters('mb_topic_allows_replies', $allow, $topic_id); }
<input type="checkbox" name="mb_forum_subscribe" value="1" /> <?php mb_forum_label('mb_form_subscribe'); ?> </label> </p><!-- .mb-form-subscribe --> <?php } // End check if subscriptions enabled. ?> <?php if (mb_is_single_forum()) { ?> <input type="hidden" name="mb_post_parent" value="<?php echo esc_attr(mb_get_forum_id()); ?> " /> <?php } ?> <?php wp_nonce_field('mb_new_forum_action', 'mb_new_forum_nonce', false); ?> </fieldset> </form>