<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[BuddyPress][9976] trunk: Add 'member_type__in' and 'member_type__not_in' support to `bp_has_members()` stack.</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta" style="font-size: 105%">
<dt style="float: left; width: 6em; font-weight: bold">Revision</dt> <dd><a style="font-weight: bold" href="http://buddypress.trac.wordpress.org/changeset/9976">9976</a><script type="application/ld+json">{"@context":"http://schema.org","@type":"EmailMessage","description":"Review this Commit","action":{"@type":"ViewAction","url":"http://buddypress.trac.wordpress.org/changeset/9976","name":"Review Commit"}}</script></dd>
<dt style="float: left; width: 6em; font-weight: bold">Author</dt> <dd>boonebgorges</dd>
<dt style="float: left; width: 6em; font-weight: bold">Date</dt> <dd>2015-06-29 14:58:47 +0000 (Mon, 29 Jun 2015)</dd>
</dl>

<pre style='padding-left: 1em; margin: 2em 0; border-left: 2px solid #ccc; line-height: 1.25; font-size: 105%; font-family: sans-serif'>Add 'member_type__in' and 'member_type__not_in' support to `bp_has_members()` stack.

Props lakrisgubben.
Fixes <a href="http://buddypress.trac.wordpress.org/ticket/6418">#6418</a>.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunksrcbpcoreclassesclassbpuserqueryphp">trunk/src/bp-core/classes/class-bp-user-query.php</a></li>
<li><a href="#trunksrcbpmembersbpmembersfunctionsphp">trunk/src/bp-members/bp-members-functions.php</a></li>
<li><a href="#trunksrcbpmembersbpmemberstemplatephp">trunk/src/bp-members/bp-members-template.php</a></li>
<li><a href="#trunktestsphpunittestcasescoreclassbpuserqueryphp">trunk/tests/phpunit/testcases/core/class-bp-user-query.php</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunksrcbpcoreclassesclassbpuserqueryphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/bp-core/classes/class-bp-user-query.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/bp-core/classes/class-bp-user-query.php 2015-06-29 12:15:06 UTC (rev 9975)
+++ trunk/src/bp-core/classes/class-bp-user-query.php   2015-06-29 14:58:47 UTC (rev 9976)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -38,6 +38,9 @@
</span><span class="cx" style="display: block; padding: 0 10px">  *                                              override all others; BP User objects will be constructed using these
</span><span class="cx" style="display: block; padding: 0 10px">  *                                              IDs only. Default: false.
</span><span class="cx" style="display: block; padding: 0 10px">  *     @type array|string      $member_type     Array or comma-separated list of member types to limit results to.
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ *     @type array|string      $member_type__in Array or comma-separated list of member types to limit results to.
+ *     @type array|string      $member_type__not_in Array or comma-separated list of member types that will be
+ *                                                 excluded from results.
</ins><span class="cx" style="display: block; padding: 0 10px">  *     @type string|bool       $meta_key        Limit results to users that have usermeta associated with this meta_key.
</span><span class="cx" style="display: block; padding: 0 10px">  *                                              Usually used with $meta_value. Default: false.
</span><span class="cx" style="display: block; padding: 0 10px">  *     @type string|bool       $meta_value      When used with $meta_key, limits results to users whose usermeta value
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -166,6 +169,8 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                'exclude'         => false,
</span><span class="cx" style="display: block; padding: 0 10px">                                'user_ids'        => false,
</span><span class="cx" style="display: block; padding: 0 10px">                                'member_type'     => '',
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                'member_type__in' => '',
+                               'member_type__not_in' => '',
</ins><span class="cx" style="display: block; padding: 0 10px">                                 'meta_key'        => false,
</span><span class="cx" style="display: block; padding: 0 10px">                                'meta_value'      => false,
</span><span class="cx" style="display: block; padding: 0 10px">                                'xprofile_query'  => false,
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -418,52 +423,22 @@
</span><span class="cx" style="display: block; padding: 0 10px">                        );
</span><span class="cx" style="display: block; padding: 0 10px">                }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                // Member type.
-               if ( ! empty( $member_type ) ) {
-                       $member_types = array();
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         // Only use $member_type__in if $member_type is not set.
+               if ( empty( $member_type ) && ! empty( $member_type__in ) ) {
+                       $member_type = $member_type__in;
+               }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        if ( ! is_array( $member_type ) ) {
-                               $member_type = preg_split( '/[,\s+]/', $member_type );
-                       }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         // Member types to exclude. Note that this takes precedence over inclusions.
+               if ( ! empty( $member_type__not_in ) ) {
+                       $member_type_clause = $this->get_sql_clause_for_member_types( $member_type__not_in, 'NOT IN' );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        foreach ( $member_type as $mt ) {
-                               if ( ! bp_get_member_type_object( $mt ) ) {
-                                       continue;
-                               }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         // Member types to include.
+               } elseif ( ! empty( $member_type ) ) {
+                       $member_type_clause = $this->get_sql_clause_for_member_types( $member_type, 'IN' );
+               }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                $member_types[] = $mt;
-                       }
-
-                       if ( ! empty( $member_types ) ) {
-                               $member_type_tq = new WP_Tax_Query( array(
-                                       array(
-                                               'taxonomy' => 'bp_member_type',
-                                               'field'    => 'name',
-                                               'operator' => 'IN',
-                                               'terms'    => $member_types,
-                                       ),
-                               ) );
-
-                               // Switch to the root blog, where member type taxonomies live.
-                               $switched = false;
-                               if ( ! bp_is_root_blog() ) {
-                                       switch_to_blog( bp_get_root_blog_id() );
-                                       $switched = true;
-                               }
-
-                               $member_type_sql_clauses = $member_type_tq->get_sql( 'u', $this->uid_name );
-
-                               if ( $switched ) {
-                                       restore_current_blog();
-                               }
-
-                               // Grab the first term_relationships clause and convert to a subquery.
-                               if ( preg_match( '/' . $wpdb->term_relationships . '\.term_taxonomy_id IN \([0-9, ]+\)/', $member_type_sql_clauses['where'], $matches ) ) {
-                                       $sql['where']['member_type'] = "u.{$this->uid_name} IN ( SELECT object_id FROM $wpdb->term_relationships WHERE {$matches[0]} )";
-                               } elseif ( false !== strpos( $member_type_sql_clauses['where'], '0 = 1' ) ) {
-                                       $sql['where']['member_type'] = $this->no_results['where'];
-                               }
-                       }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         if ( ! empty( $member_type_clause ) ) {
+                       $sql['where']['member_type'] = $member_type_clause;
</ins><span class="cx" style="display: block; padding: 0 10px">                 }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                // 'meta_key', 'meta_value' allow usermeta search
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -774,4 +749,72 @@
</span><span class="cx" style="display: block; padding: 0 10px">                        }
</span><span class="cx" style="display: block; padding: 0 10px">                }
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+       /**
+        * Get a SQL clause representing member_type include/exclusion.
+        *
+        * @since 2.4.0
+        *
+        * @param string|array $member_types Array or comma-separated list of member types.
+        * @param string       $operator     'IN' or 'NOT IN'.
+        */
+       protected function get_sql_clause_for_member_types( $member_types, $operator ) {
+               global $wpdb;
+
+               // Sanitize.
+               if ( 'NOT IN' !== $operator ) {
+                       $operator = 'IN';
+               }
+
+               // Parse and sanitize types.
+               if ( ! is_array( $member_types ) ) {
+                       $member_types = preg_split( '/[,\s+]/', $member_types );
+               }
+
+               $types = array();
+               foreach ( $member_types as $mt ) {
+                       if ( bp_get_member_type_object( $mt ) ) {
+                               $types[] = $mt;
+                       }
+               }
+
+               $tax_query = new WP_Tax_Query( array(
+                       array(
+                               'taxonomy' => 'bp_member_type',
+                               'field'    => 'name',
+                               'operator' => $operator,
+                               'terms'    => $types,
+                       ),
+               ) );
+
+               // Switch to the root blog, where member type taxonomies live.
+               $switched = false;
+               if ( ! bp_is_root_blog() ) {
+                       switch_to_blog( bp_get_root_blog_id() );
+                       $switched = true;
+               }
+
+               $sql_clauses = $tax_query->get_sql( 'u', $this->uid_name );
+
+               if ( $switched ) {
+                       restore_current_blog();
+               }
+
+               $clause = '';
+
+               // no_results clauses are the same between IN and NOT IN.
+               if ( false !== strpos( $sql_clauses['where'], '0 = 1' ) ) {
+                       $clause = $this->no_results['where'];
+
+               // The tax_query clause generated for NOT IN can be used almost as-is. We just trim the leading 'AND'.
+               } elseif ( 'NOT IN' === $operator ) {
+                       $clause = preg_replace( '/^\s*AND\s*/', '', $sql_clauses['where'] );
+
+               // IN clauses must be converted to a subquery.
+               } elseif ( preg_match( '/' . $wpdb->term_relationships . '\.term_taxonomy_id IN \([0-9, ]+\)/', $sql_clauses['where'], $matches ) ) {
+                       $clause = "u.{$this->uid_name} IN ( SELECT object_id FROM $wpdb->term_relationships WHERE {$matches[0]} )";
+               }
+
+               return $clause;
+       }
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span></span></pre></div>
<a id="trunksrcbpmembersbpmembersfunctionsphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/bp-members/bp-members-functions.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/bp-members/bp-members-functions.php     2015-06-29 12:15:06 UTC (rev 9975)
+++ trunk/src/bp-members/bp-members-functions.php       2015-06-29 14:58:47 UTC (rev 9976)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -85,6 +85,9 @@
</span><span class="cx" style="display: block; padding: 0 10px">  *     @type string       $meta_key        Limit to users with a meta_key. Default: false.
</span><span class="cx" style="display: block; padding: 0 10px">  *     @type string       $meta_value      Limit to users with a meta_value (with meta_key). Default: false.
</span><span class="cx" style="display: block; padding: 0 10px">  *     @type array|string $member_type     Array or comma-separated string of member types.
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ *     @type array|string $member_type__in Array or comma-separated string of member types.
+ *                                         `$member_type` takes precedence over this parameter.
+ *     @type array|string $member_type__not_in Array or comma-separated string of member types to be excluded.
</ins><span class="cx" style="display: block; padding: 0 10px">  *     @type mixed        $include         Limit results by user IDs. Default: false.
</span><span class="cx" style="display: block; padding: 0 10px">  *     @type int          $per_page        Results per page. Default: 20.
</span><span class="cx" style="display: block; padding: 0 10px">  *     @type int          $page            Page of results. Default: 1.
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -104,6 +107,8 @@
</span><span class="cx" style="display: block; padding: 0 10px">                'meta_key'        => false,        // Limit to users who have this piece of usermeta
</span><span class="cx" style="display: block; padding: 0 10px">                'meta_value'      => false,        // With meta_key, limit to users where usermeta matches this value
</span><span class="cx" style="display: block; padding: 0 10px">                'member_type'     => '',
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                'member_type__in' => '',
+               'member_type__not_in' => '',
</ins><span class="cx" style="display: block; padding: 0 10px">                 'include'         => false,        // Pass comma separated list of user_ids to limit to only these users
</span><span class="cx" style="display: block; padding: 0 10px">                'per_page'        => 20,           // The number of results to return per page
</span><span class="cx" style="display: block; padding: 0 10px">                'page'            => 1,            // The page to return if limiting per page
</span></span></pre></div>
<a id="trunksrcbpmembersbpmemberstemplatephp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/bp-members/bp-members-template.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/bp-members/bp-members-template.php      2015-06-29 12:15:06 UTC (rev 9975)
+++ trunk/src/bp-members/bp-members-template.php        2015-06-29 14:58:47 UTC (rev 9976)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -318,8 +318,10 @@
</span><span class="cx" style="display: block; padding: 0 10px">         * @param string       $page_arg        Optional. The string used as a query parameter in pagination links.
</span><span class="cx" style="display: block; padding: 0 10px">         *                                      Default: 'upage'.
</span><span class="cx" style="display: block; padding: 0 10px">         * @param array|string $member_type     Array or comma-separated string of member types to limit results to.
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         * @param array|string $member_type__in     Array or comma-separated string of member types to limit results to.
+        * @param array|string $member_type__not_in     Array or comma-separated string of member types to exclude from results.
</ins><span class="cx" style="display: block; padding: 0 10px">          */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        function __construct( $type, $page_number, $per_page, $max, $user_id, $search_terms, $include, $populate_extras, $exclude, $meta_key, $meta_value, $page_arg = 'upage', $member_type = '' ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ function __construct( $type, $page_number, $per_page, $max, $user_id, $search_terms, $include, $populate_extras, $exclude, $meta_key, $meta_value, $page_arg = 'upage', $member_type = '', $member_type__in = '', $member_type__not_in = '' ) {
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                $this->pag_arg  = sanitize_key( $page_arg );
</span><span class="cx" style="display: block; padding: 0 10px">                $this->pag_page = bp_sanitize_pagination_arg( $this->pag_arg, $page_number );
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -329,7 +331,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                if ( !empty( $_REQUEST['letter'] ) )
</span><span class="cx" style="display: block; padding: 0 10px">                        $this->members = BP_Core_User::get_users_by_letter( $_REQUEST['letter'], $this->pag_num, $this->pag_page, $populate_extras, $exclude );
</span><span class="cx" style="display: block; padding: 0 10px">                else
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        $this->members = bp_core_get_users( array( 'type' => $this->type, 'per_page' => $this->pag_num, 'page' => $this->pag_page, 'user_id' => $user_id, 'include' => $include, 'search_terms' => $search_terms, 'populate_extras' => $populate_extras, 'exclude' => $exclude, 'meta_key' => $meta_key, 'meta_value' => $meta_value, 'member_type' => $member_type ) );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 $this->members = bp_core_get_users( array( 'type' => $this->type, 'per_page' => $this->pag_num, 'page' => $this->pag_page, 'user_id' => $user_id, 'include' => $include, 'search_terms' => $search_terms, 'populate_extras' => $populate_extras, 'exclude' => $exclude, 'meta_key' => $meta_key, 'meta_value' => $meta_value, 'member_type' => $member_type, 'member_type__in' => $member_type__in, 'member_type__not_in' => $member_type__not_in ) );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                if ( !$max || $max >= (int) $this->members['total'] )
</span><span class="cx" style="display: block; padding: 0 10px">                        $this->total_member_count = (int) $this->members['total'];
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -523,6 +525,8 @@
</span><span class="cx" style="display: block; padding: 0 10px">  *                                                  user. When on a user's Friends page, defaults to the ID of the
</span><span class="cx" style="display: block; padding: 0 10px">  *                                                  displayed user. Otherwise defaults to 0.
</span><span class="cx" style="display: block; padding: 0 10px">  *     @type string|array          $member_type     Array or comma-separated list of member types to limit results to.
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ *     @type string|array          $member_type__in     Array or comma-separated list of member types to limit results to.
+ *     @type string|array          $member_type__not_in     Array or comma-separated list of member types to exclude from results.
</ins><span class="cx" style="display: block; padding: 0 10px">  *     @type string                $search_terms    Limit results by a search term. Default: null.
</span><span class="cx" style="display: block; padding: 0 10px">  *     @type string                $meta_key        Limit results by the presence of a usermeta key.
</span><span class="cx" style="display: block; padding: 0 10px">  *                                                  Default: false.
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -568,6 +572,8 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                'user_id'         => $user_id, // Pass a user_id to only show friends of this user
</span><span class="cx" style="display: block; padding: 0 10px">                'member_type'     => $member_type,
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                'member_type__in'     => '',
+               'member_type__not_in'     => '',
</ins><span class="cx" style="display: block; padding: 0 10px">                 'search_terms'    => null,     // Pass search_terms to filter users by their profile data
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                'meta_key'        => false,     // Only return users with this usermeta
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -604,7 +610,9 @@
</span><span class="cx" style="display: block; padding: 0 10px">                $r['meta_key'],
</span><span class="cx" style="display: block; padding: 0 10px">                $r['meta_value'],
</span><span class="cx" style="display: block; padding: 0 10px">                $r['page_arg'],
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $r['member_type']
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $r['member_type'],
+               $r['member_type__in'],
+               $r['member_type__not_in']
</ins><span class="cx" style="display: block; padding: 0 10px">         );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        /**
</span></span></pre></div>
<a id="trunktestsphpunittestcasescoreclassbpuserqueryphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/tests/phpunit/testcases/core/class-bp-user-query.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/testcases/core/class-bp-user-query.php        2015-06-29 12:15:06 UTC (rev 9975)
+++ trunk/tests/phpunit/testcases/core/class-bp-user-query.php  2015-06-29 14:58:47 UTC (rev 9976)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -499,6 +499,200 @@
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        /**
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         * @group member_types
+        */
+       public function test_member_type__in_single_value() {
+               bp_register_member_type( 'foo' );
+               bp_register_member_type( 'bar' );
+               $users = $this->factory->user->create_many( 3 );
+               bp_set_member_type( $users[0], 'foo' );
+               bp_set_member_type( $users[1], 'bar' );
+
+               $q = new BP_User_Query( array(
+                       'member_type__in' => 'bar',
+               ) );
+
+               $found = array_values( wp_list_pluck( $q->results, 'ID' ) );
+               $this->assertEquals( array( $users[1] ), $found );
+       }
+
+       /**
+        * @group member_types
+        */
+       public function test_member_type__in_array_with_single_value() {
+               bp_register_member_type( 'foo' );
+               bp_register_member_type( 'bar' );
+               $users = $this->factory->user->create_many( 3 );
+               bp_set_member_type( $users[0], 'foo' );
+               bp_set_member_type( $users[1], 'bar' );
+
+               $q = new BP_User_Query( array(
+                       'member_type__in' => array( 'bar' ),
+               ) );
+
+               $found = array_values( wp_list_pluck( $q->results, 'ID' ) );
+               $this->assertEquals( array( $users[1] ), $found );
+       }
+
+       /**
+        * @group member_types
+        */
+       public function test_member_type__in_comma_separated_values() {
+               bp_register_member_type( 'foo' );
+               bp_register_member_type( 'bar' );
+               $users = $this->factory->user->create_many( 3 );
+               bp_set_member_type( $users[0], 'foo' );
+               bp_set_member_type( $users[1], 'bar' );
+
+               $q = new BP_User_Query( array(
+                       'member_type__in' => 'foo, bar',
+               ) );
+
+               $found = array_values( wp_list_pluck( $q->results, 'ID' ) );
+               $this->assertEqualSets( array( $users[0], $users[1] ), $found );
+       }
+
+       /**
+        * @group member_types
+        */
+       public function test_member_type__in_array_with_multiple_values() {
+               bp_register_member_type( 'foo' );
+               bp_register_member_type( 'bar' );
+               $users = $this->factory->user->create_many( 3 );
+               bp_set_member_type( $users[0], 'foo' );
+               bp_set_member_type( $users[1], 'bar' );
+
+               $q = new BP_User_Query( array(
+                       'member_type__in' => array( 'foo', 'bar' ),
+               ) );
+
+               $found = array_values( wp_list_pluck( $q->results, 'ID' ) );
+               $this->assertEqualSets( array( $users[0], $users[1] ), $found );
+       }
+
+       /**
+        * @group member_types
+        */
+       public function test_member_type__in_comma_separated_values_should_discard_non_existent_taxonomies() {
+               bp_register_member_type( 'foo' );
+               bp_register_member_type( 'bar' );
+               $users = $this->factory->user->create_many( 3 );
+               bp_set_member_type( $users[0], 'foo' );
+               bp_set_member_type( $users[1], 'bar' );
+
+               $q = new BP_User_Query( array(
+                       'member_type__in' => 'foo, baz',
+               ) );
+
+               $found = array_values( wp_list_pluck( $q->results, 'ID' ) );
+               $this->assertEqualSets( array( $users[0] ), $found );
+       }
+
+       /**
+        * @group member_types
+        */
+       public function test_should_return_no_results_when_no_users_match_the_specified_member_type__in() {
+               bp_register_member_type( 'foo' );
+               $users = $this->factory->user->create_many( 3 );
+
+               $q = new BP_User_Query( array(
+                       'member_type__in' => 'foo, baz',
+               ) );
+
+               $this->assertEmpty( $q->results );
+       }
+
+       /**
+        * @group member_types
+        */
+       public function test_member_type_should_take_precedence_over_member_type__in() {
+               bp_register_member_type( 'foo' );
+               bp_register_member_type( 'bar' );
+               $users = $this->factory->user->create_many( 3 );
+               bp_set_member_type( $users[0], 'foo' );
+               bp_set_member_type( $users[1], 'bar' );
+
+               $q = new BP_User_Query( array(
+                       'member_type__in' => 'foo',
+                       'member_type' => 'bar'
+               ) );
+
+               $found = array_values( wp_list_pluck( $q->results, 'ID' ) );
+               $this->assertEqualSets( array( $users[1] ), $found );
+       }
+
+       /**
+        * @group member_types
+        */
+       public function test_member_type__not_in_returns_members_from_other_types_and_members_with_no_types() {
+               bp_register_member_type( 'foo' );
+               bp_register_member_type( 'bar' );
+               $users = $this->factory->user->create_many( 3 );
+               bp_set_member_type( $users[0], 'foo' );
+               bp_set_member_type( $users[1], 'bar' );
+
+               $q = new BP_User_Query( array(
+                       'member_type__not_in' => 'foo',
+               ) );
+
+               $found = array_values( wp_list_pluck( $q->results, 'ID' ) );
+               $this->assertEqualSets( array( $users[1], $users[2] ), $found );
+       }
+
+       /**
+        * @group member_types
+        */
+       public function test_should_return_no_results_when_all_users_match_the_specified_member_type__not_in() {
+               bp_register_member_type( 'foo' );
+               $users = $this->factory->user->create_many( 3 );
+               bp_set_member_type( $users[0], 'foo' );
+               bp_set_member_type( $users[1], 'foo' );
+               bp_set_member_type( $users[2], 'foo' );
+
+               $q = new BP_User_Query( array(
+                       'member_type__not_in' => 'foo',
+               ) );
+
+               $this->assertEmpty( $q->results );
+       }
+
+       /**
+        * @group member_types
+        */
+       public function test_member_type__not_in_takes_precedence_over_member_type() {
+               bp_register_member_type( 'foo' );
+               $users = $this->factory->user->create_many( 3 );
+               bp_set_member_type( $users[0], 'foo' );
+               bp_set_member_type( $users[1], 'foo' );
+               bp_set_member_type( $users[2], 'foo' );
+
+               $q = new BP_User_Query( array(
+                       'member_type__not_in' => 'foo',
+                       'member_type' => 'foo'
+               ) );
+
+               $this->assertEmpty( $q->results );
+       }
+
+       /**
+        * @group member_types
+        */
+       public function test_member_type__not_in_takes_precedence_over_member_type__in() {
+               bp_register_member_type( 'foo' );
+               $users = $this->factory->user->create_many( 3 );
+               bp_set_member_type( $users[0], 'foo' );
+               bp_set_member_type( $users[1], 'foo' );
+               bp_set_member_type( $users[2], 'foo' );
+
+               $q = new BP_User_Query( array(
+                       'member_type__not_in' => 'foo',
+                       'member_type__in' => 'foo'
+               ) );
+
+               $this->assertEmpty( $q->results );
+       }
+
+       /**
</ins><span class="cx" style="display: block; padding: 0 10px">          * @group cache
</span><span class="cx" style="display: block; padding: 0 10px">         * @group member_types
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span></span></pre>
</div>
</div>

</body>
</html>