function mb_set_user_topic_count($user_id)
{
    global $wpdb;
    $open_status = mb_get_open_post_status();
    $close_status = mb_get_close_post_status();
    $publish_status = mb_get_publish_post_status();
    $hidden_status = mb_get_hidden_post_status();
    $private_status = mb_get_private_post_status();
    $where = $wpdb->prepare("WHERE post_author = %d AND post_type = %s", $user_id, mb_get_topic_post_type());
    $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}')";
    $count = $wpdb->get_var("SELECT COUNT(*) FROM {$wpdb->posts} {$where} {$status_where}");
    update_user_meta($user_id, mb_get_user_topic_count_meta_key(), $count);
    return $count;
}
/**
 * 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;
}
/**
 * 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;
}
Example #4
0
 /**
  * Makes sure the correct post status is used when loading forums on the nav menus screen.  By
  * default, WordPress will only load them if they have the "publish" post status.
  *
  * @since  1.0.0
  * @access public
  * @param  object  $object
  * @return object
  */
 public function nav_menu_meta_box_object($object)
 {
     if (isset($object->name) && mb_get_forum_post_type() === $object->name) {
         $statuses = array(mb_get_open_post_status(), mb_get_close_post_status(), mb_get_publish_post_status(), mb_get_private_post_status(), mb_get_hidden_post_status(), mb_get_archive_post_status());
         $object->_default_query = wp_parse_args(array('post_status' => $statuses), $object->_default_query);
     }
     return $object;
 }
Example #5
0
/**
 * Overwrites the main query depending on the situation.
 *
 * @since  1.0.0
 * @access public
 * @param  object  $query
 * @return void
 */
function mb_pre_get_posts($query)
{
    /* If viewing an admin page or this isn't the main query, bail. */
    if (is_admin() || !$query->is_main_query()) {
        return;
    }
    /* If viewing the forum archive page. */
    if (mb_is_forum_archive()) {
        $statuses = array(mb_get_open_post_status(), mb_get_close_post_status(), mb_get_publish_post_status(), mb_get_private_post_status(), mb_get_archive_post_status());
        if (current_user_can('read_hidden_forums')) {
            $statuses[] = mb_get_hidden_post_status();
        }
        $query->set('post_type', mb_get_forum_post_type());
        $query->set('post_status', $statuses);
        $query->set('posts_per_page', mb_get_forums_per_page());
        $query->set('orderby', array('menu_order' => 'ASC', 'title' => 'ASC'));
        $query->set('post_parent', 0);
        add_filter('the_posts', 'mb_posts_hierarchy_filter', 10, 2);
    } elseif (mb_is_topic_archive()) {
        $statuses = array(mb_get_open_post_status(), mb_get_close_post_status(), mb_get_publish_post_status(), mb_get_private_post_status());
        if (current_user_can('read_hidden_topics')) {
            $statuses[] = mb_get_hidden_post_status();
        }
        $query->set('post_type', mb_get_topic_post_type());
        $query->set('post_status', $statuses);
        $query->set('posts_per_page', mb_get_topics_per_page());
        $query->set('order', 'DESC');
        $query->set('orderby', 'menu_order');
        add_filter('the_posts', 'mb_posts_super_filter', 10, 2);
    } elseif (mb_is_user_page()) {
        /* Single user forums created page. */
        if (mb_is_user_page('forums')) {
            $query->set('post_type', mb_get_forum_post_type());
            $query->set('posts_per_page', mb_get_forums_per_page());
            $query->set('order', 'ASC');
            $query->set('orderby', 'title');
            /* Single user topics created page. */
        } elseif (mb_is_user_page('topics')) {
            $query->set('post_type', mb_get_topic_post_type());
            $query->set('posts_per_page', mb_get_topics_per_page());
            $query->set('order', 'DESC');
            $query->set('orderby', 'menu_order');
            /* Single user replies created page. */
        } elseif (mb_is_user_page('replies')) {
            $query->set('post_type', mb_get_reply_post_type());
            $query->set('posts_per_page', mb_get_replies_per_page());
            $query->set('order', 'DESC');
            $query->set('orderby', 'date');
            /* Single user bookmarks saved page. */
        } elseif (mb_is_user_page('bookmarks')) {
            $user = get_user_by('slug', get_query_var('author_name'));
            $favs = get_user_meta($user->ID, mb_get_user_topic_bookmarks_meta_key(), true);
            $favs = wp_parse_id_list($favs);
            /* Empty array with `post_in` hack. @link https://core.trac.wordpress.org/ticket/28099 */
            if (empty($favs)) {
                $favs = array(0);
            }
            $query->set('post__in', $favs);
            $query->set('post_type', mb_get_topic_post_type());
            $query->set('posts_per_page', mb_get_topics_per_page());
            $query->set('order', 'DESC');
            $query->set('orderby', 'menu_order');
            add_filter('posts_where', 'mb_auth_posts_where', 10, 2);
            /* Single user topic subscriptions page. */
        } elseif (mb_is_user_page('topic-subscriptions')) {
            $user = get_user_by('slug', get_query_var('author_name'));
            $subs = mb_get_user_topic_subscriptions($user->ID);
            /* Empty array with `post_in` hack. @link https://core.trac.wordpress.org/ticket/28099 */
            if (empty($subs)) {
                $subs = array(0);
            }
            $query->set('post__in', $subs);
            $query->set('post_type', mb_get_topic_post_type());
            $query->set('posts_per_page', mb_get_topics_per_page());
            $query->set('order', 'DESC');
            $query->set('orderby', 'menu_order');
            add_filter('posts_where', 'mb_auth_posts_where', 10, 2);
            /* Single user forum subscriptions page. */
        } elseif (mb_is_user_page('forum-subscriptions')) {
            $user = get_user_by('slug', get_query_var('author_name'));
            $subs = mb_get_user_forum_subscriptions($user->ID);
            /* Empty array with `post_in` hack. @link https://core.trac.wordpress.org/ticket/28099 */
            if (empty($subs)) {
                $subs = array(0);
            }
            $query->set('post__in', $subs);
            $query->set('post_type', mb_get_forum_post_type());
            $query->set('posts_per_page', mb_get_forums_per_page());
            $query->set('order', 'DESC');
            $query->set('orderby', 'menu_order');
            add_filter('posts_where', 'mb_auth_posts_where', 10, 2);
        }
    } elseif (mb_is_search_results()) {
        $post_type = $query->get('post_type');
        /* If not searching a specific post type, make sure to search all forum-related post types. */
        if (empty($post_type) || 'any' === $post_type || !isset($_GET['mb_search_mode'])) {
            $query->set('post_type', array(mb_get_forum_post_type(), mb_get_topic_post_type(), mb_get_reply_post_type()));
        }
        $query->set('post_status', array(mb_get_open_post_status(), mb_get_close_post_status(), mb_get_publish_post_status()));
        $query->set('posts_per_page', mb_get_topics_per_page());
    } elseif (mb_is_user_archive() && get_query_var('mb_role')) {
        $role = get_query_var('mb_role');
        if ($role && in_array("mb_{$role}", array_keys(mb_get_dynamic_roles()))) {
            $query->set('mb_role', "mb_{$role}");
        }
    } elseif ($query->is_single && isset($query->query_vars['post_type']) && in_array($query->query_vars['post_type'], array(mb_get_forum_post_type(), mb_get_topic_post_type(), mb_get_reply_post_type()))) {
        add_filter('the_posts', 'mb_posts_can_read_parent');
    }
}
/**
 * Callback function for the `transition_post_status` hook.  This function saves the previous post status 
 * as metadata.  It also adds actions for more specific status changes.
 *
 * @since  1.0.0
 * @access public
 * @param  string  $new_status
 * @param  string  $old_status
 * @param  object  $post
 * @return void
 */
function mb_transition_post_status($new_status, $old_status, $post)
{
    /* Get post types. */
    $forum_type = mb_get_forum_post_type();
    $topic_type = mb_get_topic_post_type();
    $reply_type = mb_get_reply_post_type();
    /* If not one of our post types, bail. */
    if (!in_array($post->post_type, array($forum_type, $topic_type, $reply_type))) {
        return;
    }
    /* Keep track of the old post status by saving it as post meta. */
    update_post_meta($post->ID, mb_get_prev_status_meta_key(), $old_status);
    /* Get post type statuses. */
    $forum_statuses = mb_get_forum_post_statuses();
    $topic_statuses = mb_get_topic_post_statuses();
    $reply_statuses = mb_get_reply_post_statuses();
    /* Get the post statuses we need to work with. */
    $publish_status = mb_get_publish_post_status();
    $open_status = mb_get_open_post_status();
    $close_status = mb_get_close_post_status();
    $private_status = mb_get_private_post_status();
    $hidden_status = mb_get_hidden_post_status();
    $spam_status = mb_get_spam_post_status();
    $trash_status = mb_get_trash_post_status();
    /* If old status is not one of our statuses but the new is, assume we're publishing for the first time. */
    if ($forum_type === $post->post_type && !in_array($old_status, $forum_statuses) && in_array($new_status, $forum_statuses)) {
        mb_insert_forum_data($post);
    } elseif ($topic_type === $post->post_type && !in_array($old_status, $topic_statuses) && in_array($new_status, $topic_statuses)) {
        mb_insert_topic_data($post);
    } elseif ($reply_type === $post->post_type && !in_array($old_status, $reply_statuses) && in_array($new_status, $reply_statuses)) {
        mb_insert_reply_data($post);
    }
    /* Publish status change. */
    add_action("{$publish_status}_to_{$spam_status}", 'mb_publish_to_spam');
    add_action("{$publish_status}_to_{$trash_status}", 'mb_publish_to_trash');
    /* Open status change. */
    add_action("{$open_status}_to_{$spam_status}", 'mb_publish_to_spam');
    add_action("{$open_status}_to_{$trash_status}", 'mb_publish_to_trash');
    /* Close status change. */
    add_action("{$close_status}_to_{$spam_status}", 'mb_close_to_spam');
    add_action("{$close_status}_to_{$trash_status}", 'mb_close_to_trash');
    /* Private status change. */
    add_action("{$private_status}_to_{$spam_status}", 'mb_publish_to_spam');
    add_action("{$private_status}_to_{$trash_status}", 'mb_publish_to_trash');
    /* Hidden status change. */
    add_action("{$hidden_status}_to_{$spam_status}", 'mb_publish_to_spam');
    add_action("{$hidden_status}_to_{$trash_status}", 'mb_publish_to_trash');
    /* Spam status change. */
    add_action("{$spam_status}_to_{$publish_status}", 'mb_spam_to_publish');
    add_action("{$spam_status}_to_{$open_status}", 'mb_spam_to_publish');
    add_action("{$spam_status}_to_{$close_status}", 'mb_spam_to_close');
    add_action("{$spam_status}_to_{$private_status}", 'mb_spam_to_publish');
    add_action("{$spam_status}_to_{$hidden_status}", 'mb_spam_to_publish');
    /* Trash status change. */
    add_action("{$trash_status}_to_{$publish_status}", 'mb_trash_to_publish');
    add_action("{$trash_status}_to_{$open_status}", 'mb_trash_to_publish');
    add_action("{$trash_status}_to_{$close_status}", 'mb_trash_to_close');
    add_action("{$trash_status}_to_{$private_status}", 'mb_trash_to_publish');
    add_action("{$trash_status}_to_{$hidden_status}", 'mb_trash_to_publish');
}
/**
 * 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());
    }
}
Example #8
0
/**
 * Conditional check to see if a forum status allows new topics to be created.
 *
 * @since  1.0.0
 * @access public
 * @param  string  $status
 * @return bool
 */
function mb_forum_status_allows_topics($status)
{
    $statuses = array(mb_get_open_post_status(), mb_get_private_post_status(), mb_get_hidden_post_status());
    $allowed = in_array($status, $statuses) ? true : false;
    return apply_filters('mb_forum_status_allows_topics', $allowed, $status);
}