/** * Restrict access to a group regarding its 'member type' * * If a user is not logged in, he is redirected to the login form * If a user ! member type, he is redirected to the groups directory * If a user is a super admin, he can access * * @param bool $user_has_access * @param array &$no_access_args the redirect args * @return bool False if member type doesn't match, true otherwise */ function cfbgr_enqueue_current_user_has_access($user_has_access, &$no_access_args) { // If the user does not already have access bail if (empty($user_has_access)) { return $user_has_access; } // Get the member type of the group $restriction = groups_get_groupmeta(bp_get_current_group_id(), 'cf-buddypress-group-restrictions'); // Don't touch to regular groups and leave Admins access if (empty($restriction) || bp_current_user_can('bp_moderate')) { return $user_has_access; } $current_group = groups_get_current_group(); if (!is_user_logged_in()) { $user_has_access = false; $no_access_args = array('message' => __('You must log in to access the page you requested.', 'buddypress-group-restrictions'), 'root' => bp_get_group_permalink($current_group) . 'home/', 'redirect' => false); return $user_has_access; // Current user does not match the restriction } elseif ($restriction !== bp_get_member_type(bp_loggedin_user_id())) { $user_has_access = false; // Get infos about the member type $member_type_object = bp_get_member_type_object($restriction); $singular_name = ''; if (!empty($member_type_object->labels['singular_name'])) { $singular_name = $member_type_object->labels['singular_name']; } // You need to redirect to a BuddyPress page to have $no_access_args = array('mode' => 3, 'message' => sprintf(__('Sorry the group you tried to enter is only viewable for %s members', 'buddypress-group-restrictions'), esc_html($singular_name)), 'root' => bp_get_groups_directory_permalink(), 'redirect' => false); return $user_has_access; } // By default, leave BuddyPress deal with access return $user_has_access; }
/** * Is it a valid member type? * * @param type $val * @return boolean */ public function is_valid($val) { //if a registered member type, if (empty($val) || bp_get_member_type_object($val)) { return true; } return false; }
/** * Filter WP Admin users list table to include users of the specified type. * * @param WP_Query $query * * @since 2.7.0 */ public function users_table_filter_by_type($query) { global $pagenow; if (is_admin() && 'users.php' === $pagenow && !empty($_REQUEST['bp-member-type'])) { $type_slug = sanitize_text_field($_REQUEST['bp-member-type']); // Check that the type is registered. if (null == bp_get_member_type_object($type_slug)) { return; } // Get the list of users that are assigned to this member type. $type = bp_get_term_by('slug', $type_slug, bp_get_member_type_tax_name()); if (empty($type->term_id)) { return; } $user_ids = bp_get_objects_in_term($type->term_id, bp_get_member_type_tax_name()); if ($user_ids && !is_wp_error($user_ids)) { $query->set('include', (array) $user_ids); } } }
/** * Update User member type association * * @return type */ public function update_member_type() { //none of our actions are set if (empty($_REQUEST['new_member_type_top']) && empty($_REQUEST['new_member_type_bottom'])) { return; } //only admin/super admin if (!current_user_can('edit_users')) { return; } $member_type = ''; if (!empty($_REQUEST['new_member_type_top'])) { $member_type = trim($_REQUEST['new_member_type_top']); } else { $member_type = trim($_REQUEST['new_member_type_bottom']); } $input_name = 'users'; if (is_multisite() && is_network_admin()) { $input_name = 'allusers'; } $users = isset($_REQUEST[$input_name]) ? $_REQUEST[$input_name] : array(); if (empty($users)) { return; //no user selected } // $users = wp_parse_id_list($users); $member_type = sanitize_key($member_type); $member_type_object = bp_get_member_type_object($member_type); if (empty($member_type_object)) { return; //the member type does not seem to be registered } $updated = 0; foreach ($users as $user_id) { bp_set_member_type($user_id, $member_type); } $updated = 1; $this->message = sprintf(__('Updated member type for %d user(s) to %s. '), count($users), $member_type_object->labels['singular_name']); if (is_network_admin()) { $url = network_admin_url('users.php'); } else { $url = admin_url('users.php'); } $redirect = add_query_arg(array('updated' => $updated, 'bp-member-type-message' => urlencode($this->message)), $url); wp_safe_redirect($redirect); exit(0); }
/** * Process changes from the Member Type metabox. * * @since 2.2.0 */ public function process_member_type_update() { if (!isset($_POST['bp-member-type-nonce']) || !isset($_POST['bp-members-profile-member-type'])) { return; } $user_id = $this->get_user_id(); check_admin_referer('bp-member-type-change-' . $user_id, 'bp-member-type-nonce'); // Permission check. if (!current_user_can('bp_moderate') && $user_id != bp_loggedin_user_id()) { return; } // Member type string must either reference a valid member type, or be empty. $member_type = stripslashes($_POST['bp-members-profile-member-type']); if (!empty($member_type) && !bp_get_member_type_object($member_type)) { return; } /* * If an invalid member type is passed, someone's doing something * fishy with the POST request, so we can fail silently. */ if (bp_set_member_type($user_id, $member_type)) { // @todo Success messages can't be posted because other stuff happens on the page load. } }
/** * Check whether the given user has a certain member type. * * @since 2.3.0 * * @param int $user_id $user_id ID of the user. * @param string $member_type Member Type. * @return bool Whether the user has the given member type. */ function bp_has_member_type($user_id, $member_type) { // Bail if no valid member type was passed. if (empty($member_type) || !bp_get_member_type_object($member_type)) { return false; } // Get all user's member types. $types = bp_get_member_type($user_id, false); if (!is_array($types)) { return false; } return in_array($member_type, $types); }
/** * 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'. * @return string */ 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 = ''; // The 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; }
/** * Generate the current member type message. * * @since 2.3.0 * * @return string */ function bp_get_current_member_type_message() { $type_object = bp_get_member_type_object(bp_get_current_member_type()); $message = sprintf(__('Viewing members of the type: %s', 'buddypress'), '<strong>' . $type_object->labels['singular_name'] . '</strong>'); return apply_filters('bp_get_current_member_type_message', $message); }
?> </div><!-- #members-dir-search --> <?php do_action('bp_before_directory_members_tabs'); ?> <form action="" method="post" id="members-directory-form" class="dir-form"> <div id="subnav" class="item-list-tabs" role="navigation"> <ul> <?php $member_type = bp_get_current_member_type(); if ($member_type) { $member_type = bp_get_member_type_object($member_type); ?> <li class="selected" id="members-all"><a href="<?php bp_members_directory_permalink(); ?> "><?php printf(__('All %s <span>%s</span>', 'kleo_framework'), $member_type->labels['name'], bp_get_total_member_count()); ?> </a></li> <?php } else { ?> <li class="selected" id="members-all"><a href="<?php bp_members_directory_permalink(); ?> "><?php
/** * Prepare the query for user_ids. * * @since BuddyPress (1.7.0) */ public function prepare_user_ids_query() { global $wpdb, $bp; // Default query variables used here $type = ''; $per_page = 0; $page = 1; $user_id = 0; $include = false; $search_terms = false; $exclude = false; $meta_key = false; $meta_value = false; extract( $this->query_vars ); // Setup the main SQL query container $sql = array( 'select' => '', 'where' => array(), 'orderby' => '', 'order' => '', 'limit' => '' ); /** TYPE **************************************************************/ // Determines the sort order, which means it also determines where the // user IDs are drawn from (the SELECT and WHERE statements) switch ( $type ) { // 'online' query happens against the last_activity usermeta key // Filter 'bp_user_query_online_interval' to modify the // number of minutes used as an interval case 'online' : $this->uid_name = 'user_id'; $this->uid_table = $bp->members->table_name_last_activity; $sql['select'] = "SELECT u.{$this->uid_name} as id FROM {$this->uid_table} u"; $sql['where'][] = $wpdb->prepare( "u.component = %s AND u.type = 'last_activity'", buddypress()->members->id ); $sql['where'][] = $wpdb->prepare( "u.date_recorded >= DATE_SUB( UTC_TIMESTAMP(), INTERVAL %d MINUTE )", apply_filters( 'bp_user_query_online_interval', 15 ) ); $sql['orderby'] = "ORDER BY u.date_recorded"; $sql['order'] = "DESC"; break; // 'active', 'newest', and 'random' queries // all happen against the last_activity usermeta key case 'active' : case 'newest' : case 'random' : $this->uid_name = 'user_id'; $this->uid_table = $bp->members->table_name_last_activity; $sql['select'] = "SELECT u.{$this->uid_name} as id FROM {$this->uid_table} u"; $sql['where'][] = $wpdb->prepare( "u.component = %s AND u.type = 'last_activity'", buddypress()->members->id ); if ( 'newest' == $type ) { $sql['orderby'] = "ORDER BY u.user_id"; $sql['order'] = "DESC"; } elseif ( 'random' == $type ) { $sql['orderby'] = "ORDER BY rand()"; } else { $sql['orderby'] = "ORDER BY u.date_recorded"; $sql['order'] = "DESC"; } break; // 'popular' sorts by the 'total_friend_count' usermeta case 'popular' : $this->uid_name = 'user_id'; $this->uid_table = $wpdb->usermeta; $sql['select'] = "SELECT u.{$this->uid_name} as id FROM {$this->uid_table} u"; $sql['where'][] = $wpdb->prepare( "u.meta_key = %s", bp_get_user_meta_key( 'total_friend_count' ) ); $sql['orderby'] = "ORDER BY CONVERT(u.meta_value, SIGNED)"; $sql['order'] = "DESC"; break; // 'alphabetical' sorts depend on the xprofile setup case 'alphabetical' : // We prefer to do alphabetical sorts against the display_name field // of wp_users, because the table is smaller and better indexed. We // can do so if xprofile sync is enabled, or if xprofile is inactive. // // @todo remove need for bp_is_active() check if ( ! bp_disable_profile_sync() || ! bp_is_active( 'xprofile' ) ) { $this->uid_name = 'ID'; $this->uid_table = $wpdb->users; $sql['select'] = "SELECT u.{$this->uid_name} as id FROM {$this->uid_table} u"; $sql['orderby'] = "ORDER BY u.display_name"; $sql['order'] = "ASC"; // When profile sync is disabled, alphabetical sorts must happen against // the xprofile table } else { $this->uid_name = 'user_id'; $this->uid_table = $bp->profile->table_name_data; $sql['select'] = "SELECT u.{$this->uid_name} as id FROM {$this->uid_table} u"; $sql['where'][] = $wpdb->prepare( "u.field_id = %d", bp_xprofile_fullname_field_id() ); $sql['orderby'] = "ORDER BY u.value"; $sql['order'] = "ASC"; } // Alphabetical queries ignore last_activity, while BP uses last_activity // to infer spam/deleted/non-activated users. To ensure that these users // are filtered out, we add an appropriate sub-query. $sql['where'][] = "u.{$this->uid_name} IN ( SELECT ID FROM {$wpdb->users} WHERE " . bp_core_get_status_sql( '' ) . " )"; break; // Any other 'type' falls through default : $this->uid_name = 'ID'; $this->uid_table = $wpdb->users; $sql['select'] = "SELECT u.{$this->uid_name} as id FROM {$this->uid_table} u"; // In this case, we assume that a plugin is // handling order, so we leave those clauses // blank break; } /** WHERE *************************************************************/ // 'include' - User ids to include in the results $include = false !== $include ? wp_parse_id_list( $include ) : array(); $include_ids = $this->get_include_ids( $include ); if ( ! empty( $include_ids ) ) { $include_ids = implode( ',', wp_parse_id_list( $include_ids ) ); $sql['where'][] = "u.{$this->uid_name} IN ({$include_ids})"; } // 'exclude' - User ids to exclude from the results if ( false !== $exclude ) { $exclude_ids = implode( ',', wp_parse_id_list( $exclude ) ); $sql['where'][] = "u.{$this->uid_name} NOT IN ({$exclude_ids})"; } // 'user_id' - When a user id is passed, limit to the friends of the user // @todo remove need for bp_is_active() check if ( ! empty( $user_id ) && bp_is_active( 'friends' ) ) { $friend_ids = friends_get_friend_user_ids( $user_id ); $friend_ids = implode( ',', wp_parse_id_list( $friend_ids ) ); if ( ! empty( $friend_ids ) ) { $sql['where'][] = "u.{$this->uid_name} IN ({$friend_ids})"; // If the user has no friends, the query should always // return no users } else { $sql['where'][] = $this->no_results['where']; } } /** Search Terms ******************************************************/ // 'search_terms' searches user_login and user_nicename // xprofile field matches happen in bp_xprofile_bp_user_query_search() if ( false !== $search_terms ) { $search_terms = bp_esc_like( wp_kses_normalize_entities( $search_terms ) ); if ( $search_wildcard === 'left' ) { $search_terms_nospace = '%' . $search_terms; $search_terms_space = '%' . $search_terms . ' %'; } elseif ( $search_wildcard === 'right' ) { $search_terms_nospace = $search_terms . '%'; $search_terms_space = '% ' . $search_terms . '%'; } else { $search_terms_nospace = '%' . $search_terms . '%'; $search_terms_space = '%' . $search_terms . '%'; } $sql['where']['search'] = $wpdb->prepare( "u.{$this->uid_name} IN ( SELECT ID FROM {$wpdb->users} WHERE ( user_login LIKE %s OR user_login LIKE %s OR user_nicename LIKE %s OR user_nicename LIKE %s ) )", $search_terms_nospace, $search_terms_space, $search_terms_nospace, $search_terms_space ); } // Member type. if ( ! empty( $member_type ) ) { $member_types = array(); if ( ! is_array( $member_type ) ) { $member_type = preg_split( '/[,\s+]/', $member_type ); } foreach ( $member_type as $mt ) { if ( ! bp_get_member_type_object( $mt ) ) { continue; } $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. switch_to_blog( bp_get_root_blog_id() ); $member_type_sql_clauses = $member_type_tq->get_sql( 'u', $this->uid_name ); 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]} )"; } } } // 'meta_key', 'meta_value' allow usermeta search // To avoid global joins, do a separate query if ( false !== $meta_key ) { $meta_sql = $wpdb->prepare( "SELECT user_id FROM {$wpdb->usermeta} WHERE meta_key = %s", $meta_key ); if ( false !== $meta_value ) { $meta_sql .= $wpdb->prepare( " AND meta_value = %s", $meta_value ); } $found_user_ids = $wpdb->get_col( $meta_sql ); if ( ! empty( $found_user_ids ) ) { $sql['where'][] = "u.{$this->uid_name} IN (" . implode( ',', wp_parse_id_list( $found_user_ids ) ) . ")"; } else { $sql['where'][] = '1 = 0'; } } // 'per_page', 'page' - handles LIMIT if ( !empty( $per_page ) && !empty( $page ) ) { $sql['limit'] = $wpdb->prepare( "LIMIT %d, %d", intval( ( $page - 1 ) * $per_page ), intval( $per_page ) ); } else { $sql['limit'] = ''; } // Allow custom filters $sql = apply_filters_ref_array( 'bp_user_query_uid_clauses', array( $sql, &$this ) ); // Assemble the query chunks $this->uid_clauses['select'] = $sql['select']; $this->uid_clauses['where'] = ! empty( $sql['where'] ) ? 'WHERE ' . implode( ' AND ', $sql['where'] ) : ''; $this->uid_clauses['orderby'] = $sql['orderby']; $this->uid_clauses['order'] = $sql['order']; $this->uid_clauses['limit'] = $sql['limit']; do_action_ref_array( 'bp_pre_user_query', array( &$this ) ); }
/** * Set type for a member. * * @since BuddyPress (2.2.0) * * @param int $user_id ID of the user. * @param string $member_type Member type. * @param bool $append Optional. True to append this to existing types for user, * false to replace. Default: false. * @return See {@see bp_set_object_terms()}. */ function bp_set_member_type($user_id, $member_type, $append = false) { // Pass an empty $member_type to remove a user's type. if (!empty($member_type) && !bp_get_member_type_object($member_type)) { return false; } $retval = bp_set_object_terms($user_id, $member_type, 'bp_member_type', $append); // Bust the cache if the type has been updated. if (!is_wp_error($retval)) { wp_cache_delete($user_id, 'bp_member_member_type'); /** * Fires just after a user's member type has been changed. * * @since BuddyPress (2.2.0) * * @param int $user_id ID of the user whose member type has been updated. * @param string $member_type Member type. * @param bool $append Whether the type is being appended to existing types. */ do_action('bp_set_member_type', $user_id, $member_type, $append); } return $retval; }
/** * Generate the current member type message. * * @since 2.3.0 * * @return string */ function bp_get_current_member_type_message() { $type_object = bp_get_member_type_object(bp_get_current_member_type()); $message = sprintf(__('Viewing members of the type: %s', 'buddypress'), '<strong>' . $type_object->labels['singular_name'] . '</strong>'); /** * Filters the current member type message. * * @since 2.3.0 * * @param string $message Message to filter. */ return apply_filters('bp_get_current_member_type_message', $message); }
/** * Gets a label representing the field's member types. * * This label is displayed alongside the field's name on the Profile Fields Dashboard panel. * * @since 2.4.0 * * @return string */ public function get_member_type_label() { // Field 1 is always displayed to everyone, so never gets a label. if (1 == $this->id) { return ''; } // Return an empty string if no member types are registered. $all_types = bp_get_member_types(); if (empty($all_types)) { return ''; } $member_types = $this->get_member_types(); // If the field applies to all member types, show no message. $all_types[] = 'null'; if (array_values($all_types) == $member_types) { return ''; } $label = ''; if (!empty($member_types)) { $has_null = false; $member_type_labels = array(); foreach ($member_types as $member_type) { if ('null' === $member_type) { $has_null = true; continue; } else { $mt_obj = bp_get_member_type_object($member_type); $member_type_labels[] = $mt_obj->labels['name']; } } // Alphabetical sort. natcasesort($member_type_labels); $member_type_labels = array_values($member_type_labels); // Add the 'null' option to the end of the list. if ($has_null) { $member_type_labels[] = __('Users with no member type', 'buddypress'); } $label = sprintf(__('(Member types: %s)', 'buddypress'), implode(', ', array_map('esc_html', $member_type_labels))); } else { $label = '<span class="member-type-none-notice">' . __('(Unavailable to all members)', 'buddypress') . '</span>'; } return $label; }
public function test_bp_get_member_type_object_should_return_type_object() { bp_register_member_type('foo'); $this->assertInternalType('object', bp_get_member_type_object('foo')); }
function kleo_bp_profile_member_type_label() { $member_type = bp_get_member_type(bp_displayed_user_id()); if (empty($member_type)) { return; } $member_type_object = bp_get_member_type_object($member_type); if ($member_type_object) { $member_type_label = '<p class="kleo_bp_profile_member_type_label">' . esc_html($member_type_object->labels['singular_name']) . '</p>'; echo apply_filters('kleo_bp_profile_member_type_label', $member_type_label); } }
/** * Fields are saved using the Member type slug * We need to make sure to display its singular name * * @param string $value the member type slug * @return string the member type singular name */ public static function display_filter($value) { $member_type_object = bp_get_member_type_object($value); if (!$member_type_object) { return false; } else { $value = $member_type_object->labels['singular_name']; } return esc_html($value); }