/** * 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_reply_map_meta_cap($caps, $cap, $user_id, $args) { /* Checks if a user can read a specific reply. */ if ('read_post' === $cap && mb_is_reply($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) { $topic_id = $post->post_parent; /* If we have a topic and the user can't read it, don't allow reading the reply. */ if (0 < $topic_id && !user_can($user_id, 'read_post', $topic_id)) { $caps = array('do_not_allow'); /* If the user can read the topic, check if they can read the reply. */ } else { $post_type = get_post_type_object($post->post_type); if ($post_type->cap->read !== $post_type->cap->read_others_replies) { $caps[] = $post_type->cap->read_others_replies; } else { $caps = array(); } } } else { $caps = array(); } /* Meta cap for editing a single reply. */ } elseif ('edit_post' === $cap && mb_is_reply($args[0])) { $post = get_post($args[0]); $reply_obj = get_post_type_object(mb_get_reply_post_type()); // Spam topics if (mb_is_reply_spam($args[0])) { $caps[] = $reply_obj->cap->edit_spam_replies; } /* Meta cap for spamming a single reply. */ } elseif ('spam_reply' === $cap) { $caps = array(); $caps[] = user_can($user_id, 'edit_reply', $args[0]) ? 'spam_replies' : 'do_not_allow'; /* Meta cap check for accessing the reply form. */ } elseif ('access_reply_form' === $cap) { $caps = array('create_replies'); if (mb_is_single_topic()) { $topic_id = mb_get_topic_id(); $topic_status = mb_get_topic_status($topic_id); $topic_type = mb_get_topic_type($topic_id); if (!current_user_can('read_topic', $topic_id)) { $caps[] = 'do_not_allow'; } elseif (!mb_topic_allows_replies($topic_id)) { $caps[] = 'do_not_allow'; } } elseif (mb_is_reply_edit() && !user_can($user_id, 'edit_post', mb_get_reply_id())) { $caps[] = 'do_not_allow'; } } return $caps; }
/** * Creates a dropdown `<select>` for selecting the topic type in forms. * * @since 1.0.0 * @access public * @param array $args * @return string */ function mb_dropdown_topic_type($args = array()) { $defaults = array('name' => 'mb_topic_type', 'id' => 'mb_topic_type', 'selected' => mb_get_topic_type(), 'echo' => true); $args = wp_parse_args($args, $defaults); $types = mb_get_topic_type_objects(); $out = sprintf('<select name="%s" id="%s">', sanitize_html_class($args['name']), sanitize_html_class($args['id'])); if (!empty($args['selected']) && !current_user_can(mb_get_topic_type_object($args['selected'])->capability)) { $type = mb_get_topic_type_object($args['selected']); $out .= sprintf('<option value="%s"%s>%s</option>', esc_attr($type->name), selected($type->name, $args['selected'], false), $type->label); } else { foreach ($types as $type) { if (!current_user_can($type->capability)) { continue; } $out .= sprintf('<option value="%s"%s>%s</option>', esc_attr($type->name), selected($type->name, $args['selected'], false), $type->label); } } $out .= '</select>'; if (!$args['echo']) { return $out; } echo $out; }
/** * 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); }
/** * Topic attributes meta box. This handles whether the topic is sticky and the parent forum. It also * has the hidden input to save the proper `menu_order` field for the post. * * @since 1.0.0 * @access public * @param object $post * @return void */ function mb_topic_attributes_meta_box($post) { wp_nonce_field('_mb_topic_attr_nonce', 'mb_topic_attr_nonce'); $topic_type_object = get_post_type_object(mb_get_topic_post_type()); ?> <p> <label for="mb_topic_type"> <strong><?php _e('Topic Type:', 'message-board'); ?> </strong> </label> </p> <p> <?php mb_dropdown_topic_type(array('selected' => mb_get_topic_type($post->ID))); ?> </p> <p> <label for="mb_parent_forum"> <strong><?php echo $topic_type_object->labels->parent_item_colon; ?> </strong> </label> </p> <p> <?php mb_dropdown_forums(array('child_type' => mb_get_topic_post_type(), 'name' => 'parent_id', 'id' => 'mb_parent_forum', 'selected' => !empty($post->post_parent) ? $post->post_parent : mb_get_default_forum_id())); ?> </p> <?php $order = 0 != $post->ID ? $post->post_date : current_time('mysql'); ?> <input type="hidden" name="menu_order" value="<?php echo esc_attr(mysql2date('U', $order)); ?> " /> <?php }
/** * Callback for the `save_post` hook to handle meta boxes. * * @since 1.0.0 * @access public * @param int $post_id * @param object $post * @return void */ function save_post($post_id, $post) { /* Fix for attachment save issue in WordPress 3.5. @link http://core.trac.wordpress.org/ticket/21963 */ if (!is_object($post)) { $post = get_post(); } if (mb_get_topic_post_type() !== $post->post_type) { return; } if (!isset($_POST['mb_topic_attr_nonce']) || !wp_verify_nonce($_POST['mb_topic_attr_nonce'], '_mb_topic_attr_nonce')) { return; } /* Get the new topic type. */ $topic_type = sanitize_key($_POST['mb_topic_type']); if (mb_get_topic_type($post_id) !== $topic_type && mb_topic_type_exists($topic_type)) { if ('super' === $topic_type) { mb_add_super_topic($post_id); } elseif ('sticky' === $topic_type) { mb_add_sticky_topic($post_id); } elseif ('normal' === $topic_type && mb_is_topic_super($post_id)) { mb_remove_super_topic($post_id); } elseif ('normal' === $topic_type && mb_is_topic_sticky($post_id)) { mb_remove_sticky_topic($post_id); } /* Set the new topic type. */ mb_set_topic_type($post_id, $topic_type); } }