Skip to:
Content

bbPress.org

Ticket #459: 459.diff

File 459.diff, 18.5 KB (added by johnjamesjacoby, 7 years ago)

Cleaned up and mostly working. Needs testing.

  • bbpress.php

     
    218218
    219219                // Post type identifiers
    220220                $this->forum_post_type   = apply_filters( 'bbp_forum_post_type',  'forum'     );
     221                $this->forum_mod_tax_id  = apply_filters( 'bbp_forum_mod_tax_id', 'forum-mod' );
    221222                $this->topic_post_type   = apply_filters( 'bbp_topic_post_type',  'topic'     );
    222                 $this->reply_post_type   = apply_filters( 'bbp_reply_post_type',  'reply'     );
    223223                $this->topic_tag_tax_id  = apply_filters( 'bbp_topic_tag_tax_id', 'topic-tag' );
     224                $this->reply_post_type   = apply_filters( 'bbp_reply_post_type',  'reply'     );
    224225
    225226                // Status identifiers
    226227                $this->spam_status_id    = apply_filters( 'bbp_spam_post_status',    'spam'    );
     
    641642        }
    642643
    643644        /**
    644          * Register the topic tag taxonomy
     645         * Register the topic tag and forum moderator taxonomies
    645646         *
    646647         * @since bbPress (r2464)
    647648         * @uses register_taxonomy() To register the taxonomy
     
    665666                                'show_ui'               => bbp_allow_topic_tags() && current_user_can( 'bbp_topic_tags_admin' )
    666667                        )
    667668                ) );
     669
     670                // Register the forum-mod taxonomy
     671                register_taxonomy(
     672                        bbp_get_forum_mod_tax_id(),
     673                        bbp_get_forum_post_type(),
     674                        apply_filters( 'bbp_register_forum_moderator_taxonomy', array(
     675                                'labels'                => bbp_get_forum_mod_tax_labels(),
     676                                'capabilities'          => bbp_get_forum_mod_caps(),
     677                                'update_count_callback' => '_update_post_term_count',
     678                                'query_var'             => false,
     679                                'show_tagcloud'         => true,
     680                                'hierarchical'          => false,
     681                                'show_in_nav_menus'     => false,
     682                                'public'                => false,
     683                                'show_ui'               => bbp_allow_forum_mods() && current_user_can( 'bbp_forum_mods_admin' )
     684                        )
     685                ) );
    668686        }
    669687
    670688        /**
  • includes/admin/forums.php

     
    5858        private function setup_actions() {
    5959
    6060                // Add some general styling to the admin area
    61                 add_action( 'bbp_admin_head',        array( $this, 'admin_head'       ) );
     61                add_action( 'bbp_admin_head',          array( $this, 'admin_head'              ) );
    6262
    6363                // Messages
    64                 add_filter( 'post_updated_messages', array( $this, 'updated_messages' ) );
     64                add_filter( 'post_updated_messages',   array( $this, 'updated_messages'        ) );
    6565
    6666                // Metabox actions
    67                 add_action( 'add_meta_boxes',        array( $this, 'attributes_metabox'      ) );
    68                 add_action( 'save_post',             array( $this, 'attributes_metabox_save' ) );
     67                add_action( 'add_meta_boxes',          array( $this, 'attributes_metabox'      ) );
     68                add_action( 'save_post',               array( $this, 'attributes_metabox_save' ) );
    6969
     70                // Forum moderators AJAX; run at -1 to preempt built-in tag search
     71                add_action( 'wp_ajax_ajax-tag-search', array( $this, 'ajax_tag_search'         ), -1 );
     72
    7073                // Forum Column headers.
    7174                add_filter( 'manage_' . $this->post_type . '_posts_columns',        array( $this, 'column_headers' )        );
    7275
     
    255258        }
    256259
    257260        /**
     261         * Return user nicename suggestions instead of tag suggestions
     262         *
     263         * @since bbPress (r5329)
     264         *
     265         * @return Return early if not a request for forum moderators tax
     266         */
     267        public function ajax_tag_search() {
     268
     269                // Only do AJAX if this is a forum moderators tax search
     270                if ( ! isset( $_GET['tax'] ) || ( bbp_get_forum_mod_tax_id() !== $_GET['tax'] ) ) {
     271                        return;
     272                }
     273
     274                $taxonomy = sanitize_key( $_GET['tax'] );
     275                $tax      = get_taxonomy( $taxonomy );
     276                if ( empty( $tax ) ) {
     277                        wp_die( 0 );
     278                }
     279
     280                // Check permissions
     281                if ( ! current_user_can( $tax->cap->assign_terms ) ) {
     282                        wp_die( -1 );
     283                }
     284
     285                $s = stripslashes( $_GET['q'] );
     286
     287                // Replace tag delimiter with a comma if needed
     288                $comma = _x( ',', 'tag delimiter', 'bbpress' );
     289                if ( ',' !== $comma ) {
     290                        $s = str_replace( $comma, ',', $s );
     291                }
     292
     293                if ( false !== strpos( $s, ',' ) ) {
     294                        $s = explode( ',', $s );
     295                        $s = $s[ count( $s ) - 1 ];
     296                }
     297
     298                // Search on at least 2 characters
     299                $s = trim( $s );
     300                if ( strlen( $s ) < 2 ) {
     301                        wp_die(); // require 2 chars for matching
     302                }
     303
     304                // Get users
     305                $results = array();
     306                $users   = get_users( array(
     307                        'blog_id'        => 0, // All users
     308                        'fields'         => array( 'user_nicename' ),
     309                        'search'         => '*' . $s . '*',
     310                        'search_columns' => array( 'user_nicename' ),
     311                        'orderby'        => 'user_nicename'
     312                ) );
     313
     314                // Format the users into a nice array
     315                if ( ! empty( $users ) ) {
     316                        foreach( array_values( $users ) as $details ) {
     317                                $results[] = $details->user_nicename;
     318                        }
     319                }
     320
     321                // Echo results for AJAX
     322                echo join( $results, "\n" );
     323                wp_die();
     324        }
     325
     326        /**
    258327         * Pass the forum attributes for processing
    259328         *
    260329         * @since bbPress (r2746)
     
    399468         *
    400469         * Handles the admin-side opening/closing of forums
    401470         *
    402          * @since bbPress (rXXXX)
     471         * @since bbPress (r5329)
    403472         *
    404473         * @uses bbp_get_forum() To get the forum
    405474         * @uses current_user_can() To check if the user is capable of editing
     
    474543         * Display the success/error notices from
    475544         * {@link BBP_Admin::toggle_forum()}
    476545         *
    477          * @since bbPress (rXXXX)
     546         * @since bbPress (r5329)
    478547         *
    479548         * @uses bbp_get_forum() To get the forum
    480549         * @uses bbp_get_forum_title() To get the forum title of the forum
  • includes/core/filters.php

     
    236236// Capabilities
    237237add_filter( 'bbp_map_meta_caps', 'bbp_map_primary_meta_caps',   10, 4 ); // Primary caps
    238238add_filter( 'bbp_map_meta_caps', 'bbp_map_forum_meta_caps',     10, 4 ); // Forums
     239add_filter( 'bbp_map_meta_caps', 'bbp_map_forum_mod_meta_caps', 10, 4 ); // Forum moderator
    239240add_filter( 'bbp_map_meta_caps', 'bbp_map_topic_meta_caps',     10, 4 ); // Topics
    240 add_filter( 'bbp_map_meta_caps', 'bbp_map_reply_meta_caps',     10, 4 ); // Replies
    241241add_filter( 'bbp_map_meta_caps', 'bbp_map_topic_tag_meta_caps', 10, 4 ); // Topic tags
     242add_filter( 'bbp_map_meta_caps', 'bbp_map_reply_meta_caps',     10, 4 ); // Replies
    242243
    243244/** Deprecated ****************************************************************/
    244245
  • includes/core/options.php

     
    231231}
    232232
    233233/**
     234 * Are per-forum moderators allowed
     235 *
     236 * @since bbPress (r5329)
     237 * @param $default bool Optional. Default value true
     238 * @uses get_option() To get the allow tags
     239 * @return bool Are per-forum moderators allowed?
     240 */
     241function bbp_allow_forum_mods( $default = 1 ) {
     242        return (bool) apply_filters( 'bbp_allow_forum_mods', (bool) get_option( '_bbp_allow_forum_mods', $default ) );
     243}
     244
     245/**
    234246 * Is forum-wide searching allowed
    235247 *
    236248 * @since bbPress (r4970)
  • includes/forums/capabilities.php

     
    179179
    180180                /** Admin *************************************************************/
    181181
     182                // Forum admin area
    182183                case 'bbp_forums_admin' :
    183184                        $caps = array( 'keep_gate' );
    184185                        break;
     186
     187                // Forum moderator admin area
     188                case 'bbp_forum_mods_admin' :
     189                        $caps = array( 'keep_gate' );
     190                        break;
    185191        }
    186192
    187193        return apply_filters( 'bbp_map_forum_meta_caps', $caps, $cap, $user_id, $args );
    188194}
     195
     196/**
     197 * Return forum moderator capabilities
     198 *
     199 * @since bbPress (r5329)
     200 *
     201 * @uses apply_filters() Calls 'bbp_get_forum_mod_caps' with the capabilities
     202 * @return array Forum mod capabilities
     203 */
     204function bbp_get_forum_mod_caps() {
     205        return apply_filters( 'bbp_get_forum_mod_caps', array(
     206                'manage_terms' => 'keep_gate',
     207                'edit_terms'   => 'keep_gate',
     208                'delete_terms' => 'keep_gate',
     209                'assign_terms' => 'keep_gate'
     210        ) );
     211}
     212
     213/**
     214 * Maps forum moderator capabilities
     215 *
     216 * @since bbPress (r5329)
     217 *
     218 * @param array $caps Capabilities for meta capability
     219 * @param string $cap Capability name
     220 * @param int $user_id User id
     221 * @param mixed $args Arguments
     222 * @uses apply_filters() Filter capabilities map results
     223 * @return array Actual capabilities for meta capability
     224 */
     225function bbp_map_forum_mod_meta_caps( $caps, $cap, $user_id, $args ) {
     226
     227        // What capability is being checked?
     228        switch( $cap ) {
     229                case 'manage_forum_mods'    :
     230                case 'edit_forum_mods'      :
     231                case 'delete_forum_mods'    :
     232                case 'assign_forum_mods'    :
     233                case 'bbp_forum_mods_admin' :
     234
     235                        // Key Masters can always edit
     236                        if ( user_can( $user_id, 'keep_gate' ) ) {
     237                                $caps = array( 'keep_gate' );
     238                        }
     239        }
     240
     241        return apply_filters( 'bbp_map_forum_mod_meta_caps', $caps, $cap, $user_id, $args );
     242}
     243
     244/**
     245 * Get moderators of a forum
     246 *
     247 * @since bbPress (r5329)
     248 *
     249 * @param $forum_id Forum id
     250 * @uses bbp_is_forum() To make sure it is a forum
     251 * @uses bbp_get_forum_mod_tax_id() To get the forum moderator taxonomy
     252 * @uses wp_get_object_terms() To get the forum's moderator terms
     253 * @uses is_wp_error() To check for errors
     254 * @uses bbp_get_term_taxonomy_user_id() To convert terms to user ids
     255 * @return boolean Return false early, or if no moderator terms set, or
     256 * @return array User ids
     257 */
     258function bbp_get_forum_mod_ids( $forum_id = 0 ) {
     259
     260        // Bail if no forum ID
     261        $forum_id = bbp_get_forum_id( $forum_id );
     262        if ( empty( $forum_id ) ) {
     263                return false;
     264        }
     265
     266        // Bail if forum does not exist
     267        if ( ! bbp_is_forum( $forum_id ) ) {
     268                return false;
     269        }
     270
     271        // Get forum taxonomy terms
     272        $taxonomy = bbp_get_forum_mod_tax_id();
     273        $terms    = wp_get_object_terms( $forum_id, $taxonomy, array(
     274                'fields' => 'ids'
     275        ) );
     276
     277        // Bail if no terms found
     278        if ( empty( $terms ) || is_wp_error( $terms ) ) {
     279                return false;
     280        }
     281
     282        $moderators = array();
     283
     284        // Convert term ids to user ids
     285        foreach ( $terms as $term ) {
     286                $user_id = bbp_get_term_taxonomy_user_id( $term, $taxonomy );
     287                if ( !empty( $user_id ) ) {
     288                        $moderators[] = $user_id;
     289                }
     290        }
     291
     292        // Moderators found
     293        if ( !empty( $moderators ) ) {
     294                return $moderators;
     295        }
     296
     297        return false;
     298}
     299
     300/**
     301 * Get forums of a moderator
     302 *
     303 * @since bbPress (r5329)
     304 *
     305 * @param $user_id User id
     306 * @uses get_userdata() To get the user object
     307 * @uses bbp_get_forum_mod_tax_id() To get the forum moderator taxonomy
     308 * @uses get_term_by() To get the term id
     309 * @uses get_objects_in_term() Get the forums the user moderates
     310 * @uses is_wp_error() To check for errors
     311 * @uses bbp_is_forum() To make sure the objects are forums
     312 * @return boolean Return false early, or if user has no forums, or
     313 * @return array Forum ids
     314 */
     315function bbp_get_moderator_forum_ids( $user_id = 0 ) {
     316
     317        // Bail if no user ID
     318        if ( empty( $user_id ) ) {
     319                return false;
     320        }
     321
     322        // Bail if user does not eist
     323        $user = get_userdata( $user_id );
     324        if ( empty( $user ) ) {
     325                return false;
     326        }
     327
     328        // Convert user id to term id
     329        $taxonomy = bbp_get_forum_mod_tax_id();
     330        $term_id  = bbp_get_user_taxonomy_term_id( $user_id, $taxonomy );
     331
     332        // Get moderator forums
     333        $forums = get_objects_in_term( $term_id, $taxonomy );
     334
     335        // Forums found
     336        if ( empty( $forums ) || is_wp_error( $forums ) ) {
     337                return false;
     338        }
     339
     340        // Make sure the ids returned are forums
     341        $forum_ids = array();
     342        foreach ( $forums as $forum_id ) {
     343                if ( bbp_is_forum( $forum_id ) ) {
     344                        $forum_ids[] = $forum_id;
     345                }
     346        }
     347
     348        return $forum_ids;
     349}
     350
     351/**
     352 * Can a user moderate a forum?
     353 *
     354 * @since bbPress (r5329)
     355 *
     356 * @param int $user_id
     357 * @param int $forum_id
     358 * @return bool
     359 */
     360function bbp_is_user_forum_mod( $user_id = 0, $forum_id = 0 ) {
     361
     362        // Assume user cannot moderate the forum
     363        $retval    = false;
     364
     365        // Validate user ID - fallback to current user if no ID passed
     366        $user_id   = bbp_get_user_id( $user_id, false, ! empty( $user_id ) );
     367        $forum_id  = bbp_get_forum_id( $forum_id );
     368
     369        // Get forums the user can moderate
     370        $forum_ids = bbp_get_moderator_forum_ids( $user_id );
     371
     372        // Is this forum ID in the users array of forum IDs?
     373        if ( ! empty( $forum_ids ) ) {
     374                $retval = in_array( $forum_id, $forum_ids );
     375        }
     376
     377        return (bool) apply_filters( 'bbp_is_user_forum_mod', $retval, $user_id, $forum_id, $forum_ids );
     378}
     379 No newline at end of file
  • includes/forums/template.php

     
    20372037                return apply_filters( 'bbp_get_single_forum_description', $retstr, $r );
    20382038        }
    20392039
     2040/** Moderators ****************************************************************/
     2041
     2042/**
     2043 * Output the unique id of the forum moderators taxonomy
     2044 *
     2045 * @since bbPress (r5329)
     2046 *
     2047 * @uses bbp_get_forum_mod_tax_id() To get the forum modorator taxonomy ID
     2048 */
     2049function bbp_forum_mod_tax_id() {
     2050        echo bbp_get_forum_mod_tax_id();
     2051}
     2052        /**
     2053         * Return the unique id of the forum moderators taxonomy
     2054         *
     2055         * @since bbPress (r5329)
     2056         *
     2057         * @uses apply_filters() Calls 'bbp_get_forum_mod_tax_id' with the forum
     2058         *                        moderator taxonomy id
     2059         * @return string The unique forum moderators taxonomy
     2060         */
     2061        function bbp_get_forum_mod_tax_id() {
     2062                return apply_filters( 'bbp_get_forum_mod_tax_id', bbpress()->forum_mod_tax_id );
     2063        }
     2064
     2065/**
     2066 * Return array of labels used by the forum-mod taxonomy
     2067 *
     2068 * @since bbPress (r5329)
     2069 *
     2070 * @return array
     2071 */
     2072function bbp_get_forum_mod_tax_labels() {
     2073        return apply_filters( 'bbp_get_topic_tag_tax_labels', array(
     2074                'name'                       => __( 'Forum Moderators',     'bbpress' ),
     2075                'singular_name'              => __( 'Forum Moderator',      'bbpress' ),
     2076                'search_items'               => __( 'Search Moderators',    'bbpress' ),
     2077                'popular_items'              => __( 'Popular Moderators',   'bbpress' ),
     2078                'all_items'                  => __( 'All Moderators',       'bbpress' ),
     2079                'edit_item'                  => __( 'Edit Moderator',       'bbpress' ),
     2080                'update_item'                => __( 'Update Moderator',     'bbpress' ),
     2081                'add_new_item'               => __( 'Add New Moderator',    'bbpress' ),
     2082                'new_item_name'              => __( 'New Moderator Name',   'bbpress' ),
     2083                'view_item'                  => __( 'View Forum Moderator', 'bbpress' ),
     2084                'separate_items_with_commas' => __( 'Separate moderator names with commas', 'bbpress' )
     2085        ) );
     2086}
     2087
    20402088/** Forms *********************************************************************/
    20412089
    20422090/**
  • includes/replies/capabilities.php

     
    131131
    132132                                // Unknown, so map to edit_others_posts
    133133                                } else {
    134                                         $caps[] = $post_type->cap->edit_others_posts;
     134
     135                                        // If user is a per-forum moderator, make sure they can spectate
     136                                        if ( bbp_is_user_forum_mod( $user_id, bbp_get_reply_forum_id( $_post->ID ) ) ) {
     137                                                $caps = array( 'spectate' );
     138
     139                                        // Fallback to edit_others_posts
     140                                        } else {
     141                                                $caps[] = $post_type->cap->edit_others_posts;
     142                                        }
    135143                                }
    136144                        }
    137145
  • includes/topics/capabilities.php

     
    149149
    150150                                // Unknown, so map to edit_others_posts
    151151                                } else {
    152                                         $caps[] = $post_type->cap->edit_others_posts;
     152
     153                                        // If user is a per-forum moderator, make sure they can spectate
     154                                        if ( bbp_is_user_forum_mod( $user_id, bbp_get_topic_forum_id( $_post->ID ) ) ) {
     155                                                $caps = array( 'spectate' );
     156
     157                                        // Fallback to edit_others_posts
     158                                        } else {
     159                                                $caps[] = $post_type->cap->edit_others_posts;
     160                                        }
    153161                                }
    154162                        }
    155163
  • includes/users/capabilities.php

     
    3535
    3636                        // Moderators are always participants
    3737                        } else {
     38
     39                                // Default to the current cap
    3840                                $caps = array( $cap );
     41
     42                                // Bail if no post to check
     43                                if ( ( 'moderate' !== $cap ) || empty( $args[0] ) ) {
     44                                        break;
     45                                }
     46
     47                                // Get the post
     48                                $_post = get_post( $args[0] );
     49                                if ( empty( $_post ) ) {
     50                                        break;
     51                                }
     52
     53                                // Get forum ID for specific type of post
     54                                switch ( $_post->post_type ) {
     55
     56                                        // Forum
     57                                        case bbp_get_forum_post_type() :
     58                                                $forum_id = $_post->ID;
     59                                                break;
     60
     61                                        // Topic
     62                                        case bbp_get_topic_post_type() :
     63                                                $forum_id = bbp_get_topic_forum_id( $_post->ID );
     64                                                break;
     65
     66                                        // Reply
     67                                        case bbp_get_reply_post_type() :
     68                                                $forum_id = bbp_get_reply_forum_id( $_post->ID );
     69                                                break;
     70
     71                                        // Any other post type defaults to 0
     72                                        default :
     73                                                $forum_id = 0;
     74                                                break;
     75                                }
     76
     77                                // Bail if no forum ID
     78                                if ( empty( $forum_id ) ) {
     79                                        break;
     80                                }
     81
     82                                // If user is a per-forum moderator, make sure they can spectate
     83                                if ( bbp_is_user_forum_mod( $user_id, $forum_id ) ) {
     84                                        $caps = array( 'spectate' );
     85                                }
    3986                        }
    4087
    4188                        break;
  • includes/users/functions.php

     
    16571657        return bbp_bump_user_reply_count( $user_id, -1 );
    16581658}
    16591659
     1660/** User Nicename Taxonomies **************************************************/
     1661
     1662/**
     1663 * Return the term id for a given user id and taxonomy
     1664 *
     1665 * @since bbPress (r5329)
     1666 *
     1667 * @param int $user_id User id
     1668 * @param string $taxonomy Taxonomy
     1669 * @uses get_userdata() To get the user data
     1670 * @uses taxonomy_exists() To make sure the taxonomy exists
     1671 * @uses get_term_by() To get the term by name
     1672 *
     1673 * @return boolean Return false early, or if not found, or
     1674 * @return int Term id
     1675 */
     1676function bbp_get_user_taxonomy_term_id( $user_id = 0, $taxonomy = '' ) {
     1677
     1678        // Bail if no user ID
     1679        if ( empty( $user_id ) ) {
     1680                return false;
     1681        }
     1682
     1683        // Bail if user does not exist
     1684        $user = get_userdata( $user_id );
     1685        if ( empty( $user ) ) {
     1686                return false;
     1687        }
     1688
     1689        // Bail if no taxonomy
     1690        if ( empty( $taxonomy ) || ! taxonomy_exists( $taxonomy ) ) {
     1691                return false;
     1692        }
     1693
     1694        // Get the term id
     1695        $term = get_term_by( 'name', $user->user_nicename, $taxonomy );
     1696        if ( ! empty( $term ) ) {
     1697                return $term->term_id;
     1698        }
     1699
     1700        return false;
     1701}       
     1702
     1703/**
     1704 * Return the user id for a given term id and taxonomy
     1705 *
     1706 * @since bbPress (r5329)
     1707 *
     1708 * @param int $term_id Term id
     1709 * @param string $taxonomy
     1710 * @uses taxonomy_exists() To make sure the taxonomy exists
     1711 * @uses get_term() To get the term by term id
     1712 * @uses get_user_by() To get the user by nicename
     1713 *
     1714 * @return boolean Return false early, or if not found, or
     1715 * @return int User id
     1716 */
     1717function bbp_get_term_taxonomy_user_id( $term_id = 0, $taxonomy = '' ) {
     1718
     1719        // Bail if no user ID
     1720        if ( empty( $term_id ) ) {
     1721                return false;
     1722        }
     1723
     1724        // Bail if no taxonomy
     1725        if ( empty( $taxonomy ) || ! taxonomy_exists( $taxonomy ) ) {
     1726                return false;
     1727        }
     1728
     1729        // Bail if no term exists
     1730        $term = get_term( $term_id, $taxonomy );
     1731        if ( empty( $term ) ) {
     1732                return false;
     1733        }
     1734
     1735        // Get the user by nicename
     1736        $nicename = $term->name;
     1737        $user     = get_user_by( 'slug', $nicename );
     1738        if ( !empty( $user ) ) {
     1739                return $user->ID;
     1740        }
     1741
     1742        return false;
     1743}
     1744
    16601745/** Permissions ***************************************************************/
    16611746
    16621747/**