/** * Creates a new topic query and checks if there are any topics found. Note that we ue the main * WordPress query if viewing the topic archive or a single topic. This function is a wrapper * function for the standard WP `have_posts()`, but this function should be used instead because * it must also create a query of its own under some circumstances. * * @since 1.0.0 * @access public * @return bool */ function mb_topic_query() { $mb = message_board(); /* If a query has already been created, let's roll. */ if (!is_null($mb->topic_query->query)) { $have_posts = $mb->topic_query->have_posts(); if (empty($have_posts)) { wp_reset_postdata(); } return $have_posts; } /* Use the main WP query when viewing a single topic or topic archive. */ if (mb_is_single_topic() || mb_is_topic_archive() || mb_is_user_page(array('topics', 'topic-subscriptions', 'bookmarks'))) { global $wp_the_query; $mb->topic_query = $wp_the_query; } else { $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(); } $per_page = mb_get_topics_per_page(); $defaults = array('post_type' => mb_get_topic_post_type(), 'post_status' => $statuses, 'posts_per_page' => $per_page, 'paged' => get_query_var('paged'), 'orderby' => 'menu_order', 'order' => 'DESC', 'ignore_sticky_posts' => true); if (mb_is_single_forum()) { $defaults['post_parent'] = get_queried_object_id(); add_filter('the_posts', 'mb_posts_sticky_filter', 10, 2); add_filter('the_posts', 'mb_posts_super_filter', 10, 2); } $mb->topic_query = new WP_Query($defaults); } return $mb->topic_query->have_posts(); }
function mb_set_user_reply_count($user_id) { global $wpdb; // @todo check all public reply statuses $where = $wpdb->prepare("WHERE post_author = %d AND post_type = %s AND post_status = %s", $user_id, mb_get_reply_post_type(), mb_get_publish_post_status()); $count = $wpdb->get_var("SELECT COUNT(*) FROM {$wpdb->posts} {$where}"); update_user_meta($user_id, mb_get_user_reply_count_meta_key(), $count); return $count; }
/** * Creates a new sub-forum query and checks if there are any forums found. * * @since 1.0.0 * @access public * @return bool */ function mb_subforum_query() { $mb = message_board(); if (!is_null($mb->subforum_query->query)) { $have_posts = $mb->subforum_query->have_posts(); if (empty($have_posts)) { wp_reset_postdata(); $mb->subforum_query->query = null; } return $have_posts; } if ($mb->forum_query->in_the_loop) { $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(); } $defaults = array('post_type' => mb_get_forum_post_type(), 'post_status' => $statuses, 'posts_per_page' => mb_get_forums_per_page(), 'orderby' => array('menu_order' => 'ASC', 'title' => 'ASC'), 'ignore_sticky_posts' => true); $defaults['post_parent'] = mb_get_forum_id(); $mb->subforum_query = new WP_Query($defaults); return $mb->subforum_query->have_posts(); } return false; }
/** * Handles the output for custom columns. * * @since 1.0.0 * @access public * @param string $column * @param int $post_id */ public function manage_columns($column, $post_id) { switch ($column) { /* Post status column. */ case 'status': $post_type = mb_get_forum_post_type(); $status = get_post_status_object(mb_get_forum_status($post_id)); /* If the forum has the "publish" post status, change it to "open". */ if (mb_get_publish_post_status() === $status->name) { wp_update_post(array('ID' => $post_id, 'post_status' => mb_get_open_post_status())); } $url = add_query_arg(array('post_status' => $status->name, 'post_type' => $post_type), admin_url('edit.php')); printf('<a href="%s">%s</a>', $url, $status->label); break; /* Forum type column. */ /* Forum type column. */ case 'type': $post_type = mb_get_forum_post_type(); $forum_type = mb_get_forum_type_object(mb_get_forum_type($post_id)); $url = add_query_arg(array('post_type' => $post_type, 'forum_type' => $forum_type->name), admin_url('edit.php')); printf('<a href="%s">%s</a>', $url, $forum_type->label); break; /* Topic count column. */ /* Topic count column. */ case 'subforums': $subforum_count = mb_get_forum_subforum_count($post_id); $subforum_count = !empty($subforum_count) ? absint($subforum_count) : number_format_i18n(0); if (0 < $subforum_count) { printf('<a href="%s">%s</a>', add_query_arg(array('post_type' => mb_get_forum_post_type(), 'post_parent' => $post_id), admin_url('edit.php')), $subforum_count); } else { echo $subforum_count; } break; /* Topic count column. */ /* Topic count column. */ case 'topics': $topic_count = mb_get_forum_topic_count($post_id); $topic_count = !empty($topic_count) ? absint($topic_count) : number_format_i18n(0); if (0 < $topic_count && current_user_can('edit_topics')) { printf('<a href="%s">%s</a>', add_query_arg(array('post_type' => mb_get_topic_post_type(), 'post_parent' => $post_id), admin_url('edit.php')), $topic_count); } else { echo $topic_count; } break; /* Reply count column. */ /* Reply count column. */ case 'replies': $reply_count = mb_get_forum_reply_count($post_id); $reply_count = !empty($reply_count) ? absint($reply_count) : number_format_i18n(0); if (0 < $reply_count && current_user_can('edit_replies')) { printf('<a href="%s">%s</a>', add_query_arg(array('post_type' => mb_get_reply_post_type(), 'mb_forum' => $post_id), admin_url('edit.php')), $reply_count); } else { echo $reply_count; } break; /* Datetime column. */ /* Datetime column. */ case 'datetime': the_time(get_option('date_format')); echo '<br />'; the_time(get_option('time_format')); break; /* Just break out of the switch statement for everything else. */ /* Just break out of the switch statement for everything else. */ default: break; } }
/** * Resets the topic voices. * * @since 1.0.0 * @access public * @param int $topic_id * @return array */ function mb_reset_topic_voices($topic_id) { global $wpdb; $voices = $wpdb->get_col($wpdb->prepare("SELECT post_author FROM {$wpdb->posts} WHERE post_parent = %d AND post_type = %s AND post_status = %s", absint($topic_id), mb_get_reply_post_type(), mb_get_publish_post_status())); $topic_author = mb_get_topic_author_id($topic_id); $voices = array_merge(array($topic_author), (array) $voices); $voices = array_unique($voices); mb_set_topic_voices($topic_id, $voices); mb_set_topic_voice_count($topic_id, count($voices)); return $voices; }
/** * 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; }
/** * Adds sticky posts to the front of the line with any given set of posts and stickies. * * @since 1.0.0 * @access public * @param array $posts Array of post objects. * @param array $sticky_posts Array of post IDs. * @param int $forum_id Limit to specific forum. * @return array */ function mb_add_stickies($posts, $sticky_posts, $forum_id = 0) { /* Only do this if on the first page and we indeed have stickies. */ if (!is_paged() && !empty($sticky_posts)) { $num_posts = count($posts); $sticky_offset = 0; /* Loop over posts and relocate stickies to the front. */ for ($i = 0; $i < $num_posts; $i++) { if (in_array($posts[$i]->ID, $sticky_posts)) { $sticky_post = $posts[$i]; /* Remove sticky from current position. */ array_splice($posts, $i, 1); /* Move to front, after other stickies. */ array_splice($posts, $sticky_offset, 0, array($sticky_post)); /* Increment the sticky offset. The next sticky will be placed at this offset. */ $sticky_offset++; /* Remove post from sticky posts array. */ $offset = array_search($sticky_post->ID, $sticky_posts); unset($sticky_posts[$offset]); } } /* Fetch sticky posts that weren't in the query results. */ if (!empty($sticky_posts)) { $args = array('post__in' => $sticky_posts, 'post_type' => mb_get_topic_post_type(), 'post_status' => array(mb_get_open_post_status(), mb_get_close_post_status(), mb_get_publish_post_status()), 'nopaging' => true); if (0 < $forum_id) { $args['post_parent'] = $forum_id; } $stickies = get_posts($args); foreach ($stickies as $sticky_post) { array_splice($posts, $sticky_offset, 0, array($sticky_post)); $sticky_offset++; } } } return $posts; }
/** * Gets a post's previous post status. * * @since 1.0.0 * @access public * @param int $post_id * @return string */ function mb_get_prev_post_status($post_id) { $status = get_post_meta($post_id, mb_get_prev_status_meta_key(), true); if (empty($status)) { $status = mb_get_publish_post_status(); if (in_array(get_post_type($post_id), array(mb_get_forum_post_type(), mb_get_topic_post_type()))) { $status = mb_get_open_post_status(); } } return $status; }
function mb_dropdown_reply_status($args = array()) { $args['post_type'] = mb_get_reply_post_type(); $args['selected'] = !empty($args['selected']) ? $args['selected'] : mb_get_publish_post_status(); return mb_dropdown_post_status($args); }
function mb_reset_reply_positions($topic_id) { global $wpdb; $topic_id = mb_get_topic_id($topic_id); $replies = $wpdb->get_results($wpdb->prepare("SELECT ID, menu_order FROM {$wpdb->posts} WHERE post_type = %s AND post_status = %s AND post_parent = %d ORDER BY post_date ASC", mb_get_reply_post_type(), mb_get_publish_post_status(), $topic_id)); if (empty($replies)) { return false; } $reply_ids = array(); $i = 0; $update_sql = "UPDATE {$wpdb->posts} SET menu_order = CASE ID"; foreach ($replies as $reply) { $i++; $reply_ids[] = $reply->ID; $update_sql .= sprintf(" WHEN %d THEN %d", $reply->ID, $i); } $update_sql .= " END WHERE ID IN (" . implode(',', $reply_ids) . ")"; $wpdb->query($update_sql); }
/** * Handles the output for custom columns. * * @since 1.0.0 * @access public * @param string $column * @param int $post_id */ public function manage_columns($column, $post_id) { /* Post status column. */ if ('status' === $column) { $post_type = mb_get_topic_post_type(); $status = get_post_status_object(mb_get_topic_status($post_id)); if (mb_get_publish_post_status() === $status->name) { wp_update_post(array('ID' => $post_id, 'post_status' => mb_get_open_post_status())); } $url = add_query_arg(array('post_status' => $status->name, 'post_type' => $post_type), admin_url('edit.php')); printf('<a href="%s">%s</a>', $url, $status->label); /* Topic forum column. */ } elseif ('forum' === $column) { $post_type = mb_get_topic_post_type(); $forum_id = mb_get_topic_forum_id($post_id); $url = add_query_arg(array('post_type' => $post_type, 'post_parent' => $forum_id), admin_url('edit.php')); printf('<a href="%s">%s</a>', $url, mb_get_forum_title($forum_id)); /* Replies column. */ } elseif ('replies' === $column) { $reply_count = mb_get_topic_reply_count($post_id); $reply_count = !empty($reply_count) ? absint($reply_count) : number_format_i18n(0); if (0 < $reply_count && current_user_can('edit_replies')) { printf('<a href="%s">%s</a>', add_query_arg(array('post_type' => mb_get_reply_post_type(), 'post_parent' => $post_id), admin_url('edit.php')), $reply_count); } else { echo $reply_count; } /* Voices column. */ } elseif ('voices' === $column) { $voice_count = mb_get_topic_voice_count($post_id); echo !empty($voice_count) ? absint($voice_count) : number_format_i18n(0); /* Datetime column. */ } elseif ('datetime' === $column) { the_time(get_option('date_format')); echo '<br />'; the_time(get_option('time_format')); } }
/** * 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()); } }
/** * Conditional check to see whether a reply has the "publish" post status. * * @since 1.0.0 * @access public * @return bool */ function mb_is_reply_published($reply_id = 0) { $reply_id = mb_get_reply_id($reply_id); $status = mb_get_reply_status($reply_id); return apply_filters('mb_is_reply_published', mb_get_publish_post_status() === $status ? true : false, $reply_id); }
/** * Custom `submitdiv` meta box. This replaces the WordPress default because it has too many things * hardcoded that we cannot overwrite, particularly dealing with post statuses. * * @since 1.0.0 * @access public * @param object $post * @param array $args * @return void */ function mb_submit_meta_box($post, $args = array()) { $forum_type = mb_get_forum_post_type(); $topic_type = mb_get_topic_post_type(); $reply_type = mb_get_reply_post_type(); $post_type = $post->post_type; $post_status = $post->post_status; $hidden_status = 'auto-draft' === $post_status ? 'draft' : $post_status; /* If the post is a forum. */ if ($forum_type === $post_type) { $allowed_stati = mb_get_forum_post_statuses(); $status_obj = in_array($post_status, $allowed_stati) ? get_post_status_object($post_status) : get_post_status_object(mb_get_open_post_status()); /* If the post is a topic. */ } elseif ($topic_type === $post_type) { $allowed_stati = mb_get_topic_post_statuses(); $status_obj = in_array($post_status, $allowed_stati) ? get_post_status_object($post_status) : get_post_status_object(mb_get_open_post_status()); /* If the post is a reply. */ } elseif ($reply_type === $post_type) { $allowed_stati = mb_get_reply_post_statuses(); $status_obj = in_array($post_status, $allowed_stati) ? get_post_status_object($post_status) : get_post_status_object(mb_get_publish_post_status()); } ?> <div class="submitbox" id="submitpost"> <div id="minor-publishing"> <div id="misc-publishing-actions"> <div class="misc-pub-section misc-pub-post-status"> <label for="post_status"> <?php printf(__('Status: %s', 'message-board'), "<strong class='mb-current-status'>{$status_obj->label}</strong>"); ?> </label> <a href="#post-status-select" class="edit-post-status hide-if-no-js"> <span aria-hidden="true"><?php _e('Edit', 'message-board'); ?> </span> <span class="screen-reader-text"><?php _e('Edit status', 'message-board'); ?> </span> </a> <div id="post-status-select" class="hide-if-js"> <input type="hidden" name="hidden_post_status" id="hidden_post_status" value="<?php echo esc_attr($hidden_status); ?> " /> <div id="post_status"> <?php mb_dropdown_forum_status(array('selected' => $post_status, 'id' => 'post_status', 'name' => 'post_status')); ?> <a href="#post_status" class="save-post-status hide-if-no-js button"><?php _e('OK', 'message-board'); ?> </a> <a href="#post_status" class="cancel-post-status hide-if-no-js button-cancel"><?php _e('Cancel', 'message-board'); ?> </a> </div><!-- #post_status --> </div><!-- #post-status-select --> </div><!-- .misc-pub-section --> <?php /* Get the post date. */ $date_mysql = 0 != $post->ID ? $post->post_date : current_time('mysql'); /* Translators: Publish box date format. */ $date_i18n = date_i18n(__('M j, Y @ G:i', 'message-board'), strtotime($date_mysql)); ?> <div class="misc-pub-section curtime misc-pub-curtime"> <span id="timestamp"><?php printf(__('Date: %s', 'message-board'), "<strong>{$date_i18n}</strong>"); ?> </span> </div><!-- .misc-pub-curtime --> <div class="misc-pub-section"> <i class="dashicons dashicons-admin-users"></i> <?php printf(__('Author: %s', 'message-board'), '<strong>' . get_the_author_meta('display_name', $post->post_author) . '</strong>'); ?> </div><!-- .misc-pub-section --> <?php do_action('post_submitbox_misc_actions'); ?> </div><!-- #misc-publishing-actions --> <div class="clear"></div> </div><!-- #minor-publishing --> <div id="major-publishing-actions"> <?php do_action('post_submitbox_start'); ?> <div id="delete-action"> <?php if (current_user_can('delete_post', $post->ID)) { ?> <a class="submitdelete deletion" href="<?php echo get_delete_post_link($post->ID); ?> "> <?php !EMPTY_TRASH_DAYS ? _e('Delete Permanently', 'message-board') : _e('Move to Trash', 'message-board'); ?> </a> <?php } ?> </div><!-- #delete-action --> <div id="publishing-action"> <span class="spinner"></span> <?php if (0 == $post->ID || !in_array($post_status, $allowed_stati)) { ?> <input name="original_publish" type="hidden" id="original_publish" value="<?php esc_attr_e('Publish', 'message-board'); ?> " /> <?php submit_button(__('Publish', 'message-board'), 'primary button-large', 'mb-publish', false, array('accesskey' => 'p')); ?> <?php } else { ?> <input name="original_publish" type="hidden" id="original_publish" value="<?php esc_attr_e('Update', 'message-board'); ?> " /> <input name="save" type="submit" class="button button-primary button-large" id="publish" accesskey="p" value="<?php esc_attr_e('Update', 'message-board'); ?> " /> <?php } ?> </div><!-- #publishing-action --> <div class="clear"></div> </div><!-- #major-publishing-actions --> </div><!-- #submitpost --> <?php }