Skip to:
Content

BuddyPress.org


Ignore:
Timestamp:
06/29/2015 02:58:47 PM (9 years ago)
Author:
boonebgorges
Message:

Add 'member_typein' and 'member_typenot_in' support to bp_has_members() stack.

Props lakrisgubben.
Fixes #6418.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/bp-core/classes/class-bp-user-query.php

    r9819 r9976  
    3939 *                                              IDs only. Default: false.
    4040 *     @type array|string      $member_type     Array or comma-separated list of member types to limit results to.
     41 *     @type array|string      $member_type__in Array or comma-separated list of member types to limit results to.
     42 *     @type array|string      $member_type__not_in Array or comma-separated list of member types that will be
     43 *                                      excluded from results.
    4144 *     @type string|bool       $meta_key        Limit results to users that have usermeta associated with this meta_key.
    4245 *                                              Usually used with $meta_value. Default: false.
     
    167170                'user_ids'        => false,
    168171                'member_type'     => '',
     172                'member_type__in' => '',
     173                'member_type__not_in' => '',
    169174                'meta_key'        => false,
    170175                'meta_value'      => false,
     
    419424        }
    420425
    421         // Member type.
    422         if ( ! empty( $member_type ) ) {
    423             $member_types = array();
    424 
    425             if ( ! is_array( $member_type ) ) {
    426                 $member_type = preg_split( '/[,\s+]/', $member_type );
    427             }
    428 
    429             foreach ( $member_type as $mt ) {
    430                 if ( ! bp_get_member_type_object( $mt ) ) {
    431                     continue;
    432                 }
    433 
    434                 $member_types[] = $mt;
    435             }
    436 
    437             if ( ! empty( $member_types ) ) {
    438                 $member_type_tq = new WP_Tax_Query( array(
    439                     array(
    440                         'taxonomy' => 'bp_member_type',
    441                         'field'    => 'name',
    442                         'operator' => 'IN',
    443                         'terms'    => $member_types,
    444                     ),
    445                 ) );
    446 
    447                 // Switch to the root blog, where member type taxonomies live.
    448                 $switched = false;
    449                 if ( ! bp_is_root_blog() ) {
    450                     switch_to_blog( bp_get_root_blog_id() );
    451                     $switched = true;
    452                 }
    453 
    454                 $member_type_sql_clauses = $member_type_tq->get_sql( 'u', $this->uid_name );
    455 
    456                 if ( $switched ) {
    457                     restore_current_blog();
    458                 }
    459 
    460                 // Grab the first term_relationships clause and convert to a subquery.
    461                 if ( preg_match( '/' . $wpdb->term_relationships . '\.term_taxonomy_id IN \([0-9, ]+\)/', $member_type_sql_clauses['where'], $matches ) ) {
    462                     $sql['where']['member_type'] = "u.{$this->uid_name} IN ( SELECT object_id FROM $wpdb->term_relationships WHERE {$matches[0]} )";
    463                 } elseif ( false !== strpos( $member_type_sql_clauses['where'], '0 = 1' ) ) {
    464                     $sql['where']['member_type'] = $this->no_results['where'];
    465                 }
    466             }
     426        // Only use $member_type__in if $member_type is not set.
     427        if ( empty( $member_type ) && ! empty( $member_type__in ) ) {
     428            $member_type = $member_type__in;
     429        }
     430
     431        // Member types to exclude. Note that this takes precedence over inclusions.
     432        if ( ! empty( $member_type__not_in ) ) {
     433            $member_type_clause = $this->get_sql_clause_for_member_types( $member_type__not_in, 'NOT IN' );
     434
     435        // Member types to include.
     436        } elseif ( ! empty( $member_type ) ) {
     437            $member_type_clause = $this->get_sql_clause_for_member_types( $member_type, 'IN' );
     438        }
     439
     440        if ( ! empty( $member_type_clause ) ) {
     441            $sql['where']['member_type'] = $member_type_clause;
    467442        }
    468443
     
    775750        }
    776751    }
     752
     753    /**
     754     * Get a SQL clause representing member_type include/exclusion.
     755     *
     756     * @since 2.4.0
     757     *
     758     * @param string|array $member_types Array or comma-separated list of member types.
     759     * @param string       $operator     'IN' or 'NOT IN'.
     760     */
     761    protected function get_sql_clause_for_member_types( $member_types, $operator ) {
     762        global $wpdb;
     763
     764        // Sanitize.
     765        if ( 'NOT IN' !== $operator ) {
     766            $operator = 'IN';
     767        }
     768
     769        // Parse and sanitize types.
     770        if ( ! is_array( $member_types ) ) {
     771            $member_types = preg_split( '/[,\s+]/', $member_types );
     772        }
     773
     774        $types = array();
     775        foreach ( $member_types as $mt ) {
     776            if ( bp_get_member_type_object( $mt ) ) {
     777                $types[] = $mt;
     778            }
     779        }
     780
     781        $tax_query = new WP_Tax_Query( array(
     782            array(
     783                'taxonomy' => 'bp_member_type',
     784                'field'    => 'name',
     785                'operator' => $operator,
     786                'terms'    => $types,
     787            ),
     788        ) );
     789
     790        // Switch to the root blog, where member type taxonomies live.
     791        $switched = false;
     792        if ( ! bp_is_root_blog() ) {
     793            switch_to_blog( bp_get_root_blog_id() );
     794            $switched = true;
     795        }
     796
     797        $sql_clauses = $tax_query->get_sql( 'u', $this->uid_name );
     798
     799        if ( $switched ) {
     800            restore_current_blog();
     801        }
     802
     803        $clause = '';
     804
     805        // no_results clauses are the same between IN and NOT IN.
     806        if ( false !== strpos( $sql_clauses['where'], '0 = 1' ) ) {
     807            $clause = $this->no_results['where'];
     808
     809        // The tax_query clause generated for NOT IN can be used almost as-is. We just trim the leading 'AND'.
     810        } elseif ( 'NOT IN' === $operator ) {
     811            $clause = preg_replace( '/^\s*AND\s*/', '', $sql_clauses['where'] );
     812
     813        // IN clauses must be converted to a subquery.
     814        } elseif ( preg_match( '/' . $wpdb->term_relationships . '\.term_taxonomy_id IN \([0-9, ]+\)/', $sql_clauses['where'], $matches ) ) {
     815            $clause = "u.{$this->uid_name} IN ( SELECT object_id FROM $wpdb->term_relationships WHERE {$matches[0]} )";
     816        }
     817
     818        return $clause;
     819    }
    777820}
Note: See TracChangeset for help on using the changeset viewer.