Skip to:
Content

BuddyPress.org

Changeset 10022


Ignore:
Timestamp:
07/21/2015 02:00:38 PM (11 years ago)
Author:
boonebgorges
Message:

Allow xProfile fields to be restricted to users belonging to one or more member types.

A new metabox on the profile field edit panel allows the administrator to
select the member types to which the field is applicable. Admins can also
choose to have a field apply to users who do not belong to any member type.
Information about a field's member type associations is displayed on the
Users > Profile Fields page, alongside each field name.

During registration, the only fields that are displayed are those that are
unrestricted - that is, those available to all users, regardless of member type
(or lack thereof).

This changeset introduces a number of new methods on BP_XProfile_Field that
developers should use to manipulate member type information:
get_member_types(), set_member_types(), and the static
get_fields_for_member_type(). In addition to member types that have been
explicitly registered, 'null' is a pseudo-type representing users who do not
belong to a member type.

This changeset introduces a blacklist of illegal member type names. By default,
the blacklist includes 'any', 'null', and '_none'. Use the
'bp_member_type_illegal_names' filter to add names to the blacklist.

Props Offereins, boonebgorges, tanner m, imath.
See #5192.

Location:
trunk
Files:
2 added
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/bp-members/bp-members-functions.php

    r9977 r10022  
    25242524        $member_type = sanitize_key( $member_type );
    25252525
     2526        /**
     2527         * Filters the list of illegal member type names.
     2528         *
     2529         * - 'any' is a special pseudo-type, representing items unassociated with any member type.
     2530         * - 'null' is a special pseudo-type, representing users without any type.
     2531         * - '_none' is used internally to denote an item that should not apply to any member types.
     2532         *
     2533         * @since BuddyPress (2.4.0)
     2534         *
     2535         * @param array $illegal_names Array of illegal names.
     2536         */
     2537        $illegal_names = apply_filters( 'bp_member_type_illegal_names', array( 'any', 'null', '_none' ) );
     2538        if ( in_array( $member_type, $illegal_names, true ) ) {
     2539                return new WP_Error( 'bp_member_type_illegal_name', __( 'You may not register a member type with this name.', 'buddypress' ), $member_type );
     2540        }
     2541
    25262542        // Store the post type name as data in the object (not just as the array key).
    25272543        $r['name'] = $member_type;
  • trunk/src/bp-xprofile/admin/css/admin.css

    r9819 r10022  
    275275        margin-bottom: 0;
    276276}
     277
     278span.member-type-none-notice,
     279p.member-type-none-notice {
     280        color: #f00;
     281}
     282
     283.hide {
     284        display: none;
     285        visibility: hidden;
     286}
  • trunk/src/bp-xprofile/admin/js/admin.js

    r9819 r10022  
    9797}
    9898
     99/**
     100 * @summary Toggles "no member type" notice.
     101 *
     102 * @since BuddyPress (2.4.0)
     103 */
     104function toggle_no_member_type_notice() {
     105        var $member_type_checkboxes = jQuery( 'input.member-type-selector' );
     106
     107        // No checkboxes? Nothing to do.
     108        if ( ! $member_type_checkboxes.length ) {
     109                return;
     110        }
     111
     112        var has_checked = false;
     113        $member_type_checkboxes.each( function() {
     114                if ( jQuery( this ).is( ':checked' ) ) {
     115                        has_checked = true;
     116                        return false;
     117                }
     118        } );
     119
     120        if ( has_checked ) {
     121                jQuery( 'p.member-type-none-notice' ).addClass( 'hide' );
     122        } else {
     123                jQuery( 'p.member-type-none-notice' ).removeClass( 'hide' );
     124        }
     125}
     126
    99127var fixHelper = function(e, ui) {
    100128        ui.children().each(function() {
    … …  
    152180        // Set focus in Field Title, if we're on the right page
    153181        jQuery( '#bp-xprofile-add-field #title' ).focus();
     182
     183        // Set up the notice that shows when no member types are selected for a field.
     184        toggle_no_member_type_notice();
     185        jQuery( 'input.member-type-selector' ).on( 'change', function() {
     186                toggle_no_member_type_notice();
     187        } );
    154188
    155189        // Set up deleting options ajax
  • trunk/src/bp-xprofile/bp-xprofile-admin.php

    r9974 r10022  
    362362                                }
    363363
     364                                // Set member types.
     365                                if ( isset( $_POST['has-member-types'] ) ) {
     366                                        $member_types = array();
     367                                        if ( isset( $_POST['member-types'] ) ) {
     368                                                $member_types = stripslashes_deep( $_POST['member-types'] );
     369                                        }
     370
     371                                        $field->set_member_types( $member_types );
     372                                }
     373
    364374                                // Validate default visibility
    365375                                if ( ! empty( $_POST['default-visibility'] ) && in_array( $_POST['default-visibility'], wp_list_pluck( bp_xprofile_get_visibility_levels(), 'id' ) ) ) {
    … …  
    500510                                <?php if ( bp_get_the_profile_field_is_required()                         ) : ?><?php esc_html_e( '(Required)', 'buddypress' ); endif; ?>
    501511                                <?php if ( bp_xprofile_get_meta( $field->id, 'field', 'signup_position' ) ) : ?><?php esc_html_e( '(Sign-up)',  'buddypress' ); endif; ?>
     512                                <?php if ( bp_get_member_types() ) : echo $field->get_member_type_label(); endif; ?>
    502513
    503514                                <?php
  • trunk/src/bp-xprofile/bp-xprofile-cache.php

    r9819 r10022  
    235235add_action( 'xprofile_fields_saved_field',   'xprofile_clear_profile_field_object_cache' );
    236236add_action( 'xprofile_fields_deleted_field', 'xprofile_clear_profile_field_object_cache' );
     237
     238/**
     239 * Clears member_type cache when a field's member types are updated.
     240 *
     241 * @since BuddyPress (2.4.0)
     242 */
     243function bp_xprofile_clear_member_type_cache() {
     244        wp_cache_delete( 'field_member_types', 'bp_xprofile' );
     245}
     246add_action( 'bp_xprofile_field_set_member_type', 'bp_xprofile_clear_member_type_cache' );
    237247
    238248/**
  • trunk/src/bp-xprofile/bp-xprofile-template.php

    r10015 r10022  
    111111
    112112        /**
    113          * Get activity items, as specified by parameters
     113         * Get activity items, as specified by parameters.
     114         *
     115         * @see BP_XProfile_Group::get() for more details about parameters.
     116         *
     117         * @since BuddyPress (2.4.0) Introduced `$member_type` argument.
    114118         *
    115119         * @param array $args {
    116120         *     An array of arguments. All items are optional.
    117121         *
    118          *     @type int       $user_id                 Fetch field data for this user ID
    119          *     @type int       $profile_group_id        Field group to fetch fields & data for
    120          *     @type int|bool  $hide_empty_groups       Should empty field groups be skipped
    121          *     @type int|bool  $fetch_fields            Fetch fields for field group
    122          *     @type int|bool  $fetch_field_data        Fetch field data for fields in group
    123          *     @type array     $exclude_groups          Exclude these field groups
    124          *     @type array     $exclude_fields          Exclude these fields
    125          *     @type int|bool  $hide_empty_fields       Should empty fields be skipped
    126          *     @type int|bool  $fetch_visibility_level  Fetch visibility levels
    127          *     @type int|bool  $update_meta_cache       Should metadata cache be updated
     122         *     @type int          $user_id                 Fetch field data for this user ID.
     123         *     @type string|array $member_type             Limit results to those matching member type(s).
     124         *     @type int          $profile_group_id        Field group to fetch fields & data for.
     125         *     @type int|bool     $hide_empty_groups       Should empty field groups be skipped.
     126         *     @type int|bool     $fetch_fields            Fetch fields for field group.
     127         *     @type int|bool     $fetch_field_data        Fetch field data for fields in group.
     128         *     @type array        $exclude_groups          Exclude these field groups.
     129         *     @type array        $exclude_fields          Exclude these fields.
     130         *     @type int|bool     $hide_empty_fields       Should empty fields be skipped.
     131         *     @type int|bool     $fetch_visibility_level  Fetch visibility levels.
     132         *     @type int|bool     $update_meta_cache       Should metadata cache be updated.
    128133         * }
    129134         */
    … …  
    154159                        'profile_group_id'       => false,
    155160                        'user_id'                => false,
     161                        'member_type'            => 'any',
    156162                        'hide_empty_groups'      => false,
    157163                        'hide_empty_fields'      => false,
    … …  
    318324 *     Array of arguments. See BP_XProfile_Group::get() for full description. Those arguments whose defaults differ
    319325 *     from that method are described here:
    320  *     @type bool $hide_empty_groups      Default: true.
    321  *     @type bool $hide_empty_fields      Defaults to true on the Dashboard, on a user's Edit Profile page,
    322  *                                        or during registration. Otherwise false.
    323  *     @type bool $fetch_visibility_level Defaults to true when an admin is viewing a profile, or when a user is
    324  *                                        viewing her own profile, or during registration. Otherwise false.
    325  *     @type bool $fetch_fields           Default: true.
    326  *     @type bool $fetch_field_data       Default: true.
     326 *     @type string|array $member_type            Default: 'any'.
     327 *     @type bool         $hide_empty_groups      Default: true.
     328 *     @type bool         $hide_empty_fields      Defaults to true on the Dashboard, on a user's Edit Profile page,
     329 *                                                or during registration. Otherwise false.
     330 *     @type bool         $fetch_visibility_level Defaults to true when an admin is viewing a profile, or when a user is
     331 *                                                viewing her own profile, or during registration. Otherwise false.
     332 *     @type bool         $fetch_fields           Default: true.
     333 *     @type bool         $fetch_field_data       Default: true.
    327334 * }
    328335 *
    … …  
    346353        $r = bp_parse_args( $args, array(
    347354                'user_id'                => bp_displayed_user_id(),
     355                'member_type'            => 'any',
    348356                'profile_group_id'       => false,
    349357                'hide_empty_groups'      => true,
  • trunk/src/bp-xprofile/classes/class-bp-xprofile-field.php

    r9986 r10022  
    123123         */
    124124        public $data;
     125
     126        /**
     127         * Member types to which the profile field should be applied.
     128         *
     129         * @since BuddyPress (2.4.0)
     130         * @access protected
     131         * @var array Array of member types.
     132         */
     133        protected $member_types;
    125134
    126135        /**
    … …  
    458467        }
    459468
     469        /**
     470         * Gets the member types to which this field should be available.
     471         *
     472         * Will not return inactive member types, even if associated metadata is found.
     473         *
     474         * 'null' is a special pseudo-type, which represents users that do not have a member type.
     475         *
     476         * @since BuddyPress (2.4.0)
     477         *
     478         * @return array Array of member type names.
     479         */
     480        public function get_member_types() {
     481                if ( ! is_null( $this->member_types ) ) {
     482                        return $this->member_types;
     483                }
     484
     485                $raw_types = bp_xprofile_get_meta( $this->id, 'field', 'member_type', false );
     486
     487                // If `$raw_types` is not an array, it probably means this is a new field (id=0).
     488                if ( ! is_array( $raw_types ) ) {
     489                        $raw_types = array();
     490                }
     491
     492                // If '_none' is found in the array, it overrides all types.
     493                $types = array();
     494                if ( ! in_array( '_none', $raw_types ) ) {
     495                        $registered_types = bp_get_member_types();
     496
     497                        // Eliminate invalid member types saved in the database.
     498                        foreach ( $raw_types as $raw_type ) {
     499                                // 'null' is a special case - it represents users without a type.
     500                                if ( 'null' === $raw_type || isset( $registered_types[ $raw_type ] ) ) {
     501                                        $types[] = $raw_type;
     502                                }
     503                        }
     504
     505                        // If no member types have been saved, intepret as *all* member types.
     506                        if ( empty( $types ) ) {
     507                                $types = array_values( $registered_types );
     508
     509                                // + the "null" type, ie users without a type.
     510                                $types[] = 'null';
     511                        }
     512                }
     513
     514                /**
     515                 * Filters the member types to which an XProfile object should be applied.
     516                 *
     517                 * @since BuddyPress (2.4.0)
     518                 *
     519                 * @param array             $types Member types.
     520                 * @param BP_XProfile_Field $field Field object.
     521                 */
     522                $this->member_types = apply_filters( 'bp_xprofile_field_member_types', $types, $this );
     523
     524                return $this->member_types;
     525        }
     526
     527        /**
     528         * Sets the member types for this field.
     529         *
     530         * @since BuddyPress (2.4.0)
     531         *
     532         * @param array $member_types Array of member types. Can include 'null' (users with no type) in addition to any
     533         *                            registered types.
     534         * @param bool  $append       Whether to append to existing member types. If false, all existing member type
     535         *                            associations will be deleted before adding your `$member_types`. Default false.
     536         * @return array Member types for the current field, after being saved.
     537         */
     538        public function set_member_types( $member_types, $append = false ) {
     539                // Unset invalid member types.
     540                $types = array();
     541                foreach ( $member_types as $member_type ) {
     542                        // 'null' is a special case - it represents users without a type.
     543                        if ( 'null' === $member_type || bp_get_member_type_object( $member_type ) ) {
     544                                $types[] = $member_type;
     545                        }
     546                }
     547
     548                // When `$append` is false, delete all existing types before adding new ones.
     549                if ( ! $append ) {
     550                        bp_xprofile_delete_meta( $this->id, 'field', 'member_type' );
     551
     552                        /*
     553                         * We interpret an empty array as disassociating the field from all types. This is
     554                         * represented internally with the '_none' flag.
     555                         */
     556                        if ( empty( $types ) ) {
     557                                bp_xprofile_add_meta( $this->id, 'field', 'member_type', '_none' );
     558                        }
     559                }
     560
     561                /*
     562                 * Unrestricted fields are represented in the database as having no 'member_type'.
     563                 * We detect whether a field is being set to unrestricted by checking whether the
     564                 * list of types passed to the method is the same as the list of registered types,
     565                 * plus the 'null' pseudo-type.
     566                 */
     567                $_rtypes  = bp_get_member_types();
     568                $rtypes   = array_values( $_rtypes );
     569                $rtypes[] = 'null';
     570
     571                sort( $types );
     572                sort( $rtypes );
     573
     574                // Only save if this is a restricted field.
     575                if ( $types !== $rtypes ) {
     576                        // Save new types.
     577                        foreach ( $types as $type ) {
     578                                bp_xprofile_add_meta( $this->id, 'field', 'member_type', $type );
     579                        }
     580                }
     581
     582                // Reset internal cache of member types.
     583                $this->member_types = null;
     584
     585                /**
     586                 * Fires after a field's member types have been updated.
     587                 *
     588                 * @since BuddyPress (2.4.0)
     589                 *
     590                 * @param BP_XProfile_Field $field Field object.
     591                 */
     592                do_action( 'bp_xprofile_field_set_member_type', $this );
     593
     594                // Refetch fresh items from the database.
     595                return $this->get_member_types();
     596        }
     597
     598        /**
     599         * Gets a label representing the field's member types.
     600         *
     601         * This label is displayed alongside the field's name on the Profile Fields Dashboard panel.
     602         *
     603         * @since BuddyPress (2.4.0)
     604         *
     605         * @return string
     606         */
     607        public function get_member_type_label() {
     608                // Field 1 is always displayed to everyone, so never gets a label.
     609                if ( 1 == $this->id ) {
     610                        return '';
     611                }
     612
     613                // Return an empty string if no member types are registered.
     614                $all_types = bp_get_member_types();
     615                if ( empty( $all_types ) ) {
     616                        return '';
     617                }
     618
     619                $member_types = $this->get_member_types();
     620
     621                // If the field applies to all member types, show no message.
     622                $all_types[] = 'null';
     623                if ( array_values( $all_types ) == $member_types ) {
     624                        return '';
     625                }
     626
     627                $label = '';
     628                if ( ! empty( $member_types ) ) {
     629                        $has_null = false;
     630                        $member_type_labels = array();
     631                        foreach ( $member_types as $member_type ) {
     632                                if ( 'null' === $member_type ) {
     633                                        $has_null = true;
     634                                        continue;
     635                                } else {
     636                                        $mt_obj = bp_get_member_type_object( $member_type );
     637                                        $member_type_labels[] = $mt_obj->labels['name'];
     638                                }
     639                        }
     640
     641                        // Alphabetical sort.
     642                        natcasesort( $member_type_labels );
     643                        $member_type_labels = array_values( $member_type_labels );
     644
     645                        // Add the 'null' option to the end of the list.
     646                        if ( $has_null ) {
     647                                $member_type_labels[] = __( 'Users with no member type', 'buddypress' );
     648                        }
     649
     650                        $label = sprintf( __( '(Member types: %s)', 'buddypress' ), implode( ', ', array_map( 'esc_html', $member_type_labels ) ) );
     651                } else {
     652                        $label = '<span class="member-type-none-notice">' . __( '(Unavailable to all members)', 'buddypress' ) . '</span>';
     653                }
     654
     655                return $label;
     656        }
     657
    460658        /** Static Methods ********************************************************/
    461659
    … …  
    572770
    573771                return false;
     772        }
     773
     774        /**
     775         * Gets the IDs of fields applicable for a given member type or array of member types.
     776         *
     777         * @since BuddyPress (2.4.0)
     778         *
     779         * @param string|array $member_types Member type or array of member types. Use 'any' to return unrestricted
     780         *                                   fields (those available for anyone, regardless of member type).
     781         * @return array Multi-dimensional array, with field IDs as top-level keys, and arrays of member types
     782         *               associated with each field as values.
     783         */
     784        public static function get_fields_for_member_type( $member_types ) {
     785                global $wpdb;
     786
     787                $fields = array();
     788
     789                if ( empty( $member_types ) ) {
     790                        $member_types = array( 'any' );
     791                } elseif ( ! is_array( $member_types ) ) {
     792                        $member_types = array( $member_types );
     793                }
     794
     795                $bp = buddypress();
     796
     797                // Pull up all recorded field member type data.
     798                $mt_meta = wp_cache_get( 'field_member_types', 'bp_xprofile' );
     799                if ( false === $mt_meta ) {
     800                        $mt_meta = $wpdb->get_results( "SELECT object_id, meta_value FROM {$bp->profile->table_name_meta} WHERE meta_key = 'member_type' AND object_type = 'field'" );
     801                        wp_cache_set( 'field_member_types', $mt_meta, 'bp_xprofile' );
     802                }
     803
     804                // Keep track of all fields with recorded member_type metadata.
     805                $all_recorded_field_ids = wp_list_pluck( $mt_meta, 'object_id' );
     806
     807                // Sort member_type matches in arrays, keyed by field_id.
     808                foreach ( $mt_meta as $_mt_meta ) {
     809                        if ( ! isset( $fields[ $_mt_meta->object_id ] ) ) {
     810                                $fields[ $_mt_meta->object_id ] = array();
     811                        }
     812
     813                        $fields[ $_mt_meta->object_id ][] = $_mt_meta->meta_value;
     814                }
     815
     816                /*
     817                 * Filter out fields that don't match any passed types, or those marked '_none'.
     818                 * The 'any' type is implicitly handled here: it will match no types.
     819                 */
     820                foreach ( $fields as $field_id => $field_types ) {
     821                        if ( ! array_intersect( $field_types, $member_types ) ) {
     822                                unset( $fields[ $field_id ] );
     823                        }
     824                }
     825
     826                // Any fields with no member_type metadata are available to all member types.
     827                if ( ! in_array( '_none', $member_types ) ) {
     828                        if ( ! empty( $all_recorded_field_ids ) ) {
     829                                $all_recorded_field_ids_sql = implode( ',', array_map( 'absint', $all_recorded_field_ids ) );
     830                                $unrestricted_field_ids = $wpdb->get_col( "SELECT id FROM {$bp->profile->table_name_fields} WHERE id NOT IN ({$all_recorded_field_ids_sql})" );
     831                        } else {
     832                                $unrestricted_field_ids = $wpdb->get_col( "SELECT id FROM {$bp->profile->table_name_fields}" );
     833                        }
     834
     835                        // Append the 'null' pseudo-type.
     836                        $all_member_types   = bp_get_member_types();
     837                        $all_member_types   = array_values( $all_member_types );
     838                        $all_member_types[] = 'null';
     839
     840                        foreach ( $unrestricted_field_ids as $unrestricted_field_id ) {
     841                                $fields[ $unrestricted_field_id ] = $all_member_types;
     842                        }
     843                }
     844
     845                return $fields;
    574846        }
    575847
    … …  
    718990                                                        // Output the required metabox
    719991                                                        $this->required_metabox();
     992
     993                                                        // Output the Member Types metabox.
     994                                                        $this->member_type_metabox();
    720995
    721996                                                        // Output the field visibility metaboxes
    … …  
    8621137
    8631138        <?php
     1139        }
     1140
     1141        /**
     1142         * Private method used to output field Member Type metabox.
     1143         *
     1144         * @since BuddyPress (2.4.0)
     1145         */
     1146        private function member_type_metabox() {
     1147
     1148                // The primary field is for all, so bail.
     1149                if ( 1 === (int) $this->id ) {
     1150                        return;
     1151                }
     1152
     1153                // Bail when no member types are registered.
     1154                if ( ! $member_types = bp_get_member_types( array(), 'objects' ) ) {
     1155                        return;
     1156                }
     1157
     1158                $field_member_types = $this->get_member_types();
     1159
     1160                ?>
     1161
     1162                <div id="member-types-div" class="postbox">
     1163                        <h3><?php _e( 'Member Types', 'buddypress' ); ?></h3>
     1164                        <div class="inside">
     1165                                <p class="description"><?php _e( 'This field should be available to:', 'buddypress' ); ?></p>
     1166
     1167                                <ul>
     1168                                        <?php foreach ( $member_types as $member_type ) : ?>
     1169                                        <li>
     1170                                                <label>
     1171                                                        <input name="member-types[]" class="member-type-selector" type="checkbox" value="<?php echo $member_type->name; ?>" <?php checked( in_array( $member_type->name, $field_member_types ) ); ?>/>
     1172                                                        <?php echo $member_type->labels['name']; ?>
     1173                                                </label>
     1174                                        </li>
     1175                                        <?php endforeach; ?>
     1176
     1177                                        <li>
     1178                                                <label>
     1179                                                        <input name="member-types[]" class="member-type-selector" type="checkbox" value="null" <?php checked( in_array( 'null', $field_member_types ) ); ?>/>
     1180                                                        <?php _e( 'Users with no member type', 'buddypress' ); ?>
     1181                                                </label>
     1182                                        </li>
     1183
     1184                                </ul>
     1185                                <p class="description member-type-none-notice<?php if ( ! empty( $field_member_types ) ) : ?> hide<?php endif; ?>"><?php _e( 'Unavailable to all members.', 'buddypress' ) ?></p>
     1186                        </div>
     1187
     1188                        <input type="hidden" name="has-member-types" value="1" />
     1189                </div>
     1190
     1191                <?php
    8641192        }
    8651193
  • trunk/src/bp-xprofile/classes/class-bp-xprofile-group.php

    r10009 r10022  
    233233         *      @type int   $user_id           Required if you want to load a specific user's data.
    234234         *                                     Default: displayed user's ID.
     235         *      @type array|string $member_type Limit fields by those restricted to a given member type, or array of
     236         *                                      member types. If `$user_id` is provided, the value of `$member_type`
     237         *                                      will be overridden by the member types of the provided user. The
     238         *                                      special value of 'any' will return only those fields that are
     239         *                                      unrestricted by member type - i.e., those applicable to any type.
    235240         *      @type bool  $hide_empty_groups True to hide groups that don't have any fields. Default: false.
    236241         *      @type bool  $hide_empty_fields True to hide fields where the user has not provided data. Default: false.
    … …  
    252257                        'profile_group_id'       => false,
    253258                        'user_id'                => bp_displayed_user_id(),
     259                        'member_type'            => false,
    254260                        'hide_empty_groups'      => false,
    255261                        'hide_empty_fields'      => false,
    … …  
    319325                $exclude_fields_cs  = implode( ',', $exclude_fields_cs );
    320326
    321                 // Setup IN query for field IDs
     327                // Set up NOT IN query for excluded field IDs.
    322328                if ( ! empty( $exclude_fields_cs ) ) {
    323329                        $exclude_fields_sql = "AND id NOT IN ({$exclude_fields_cs})";
    … …  
    326332                }
    327333
     334                // Set up IN query for included field IDs.
     335                $include_field_ids = array();
     336
     337                // Member-type restrictions.
     338                if ( bp_get_member_types() ) {
     339                        if ( $r['user_id'] || false !== $r['member_type'] ) {
     340                                $member_types = $r['member_type'];
     341                                if ( $r['user_id'] ) {
     342                                        $member_types = bp_get_member_type( $r['user_id'], false );
     343                                        if ( empty( $member_types ) ) {
     344                                                $member_types = array( 'null' );
     345                                        }
     346                                }
     347
     348                                $member_types_fields = BP_XProfile_Field::get_fields_for_member_type( $member_types );
     349                                $include_field_ids += array_keys( $member_types_fields );
     350                        }
     351                }
     352
     353                $in_sql = '';
     354                if ( ! empty( $include_field_ids ) ) {
     355                        $include_field_ids_cs = implode( ',', array_map( 'intval', $include_field_ids ) );
     356                        $in_sql = " AND id IN ({$include_field_ids_cs}) ";
     357                }
     358
    328359                // Fetch the fields
    329                 $fields    = $wpdb->get_results( "SELECT id, name, description, type, group_id, is_required FROM {$bp->profile->table_name_fields} WHERE group_id IN ( {$group_ids_in} ) AND parent_id = 0 {$exclude_fields_sql} ORDER BY field_order" );
     360                $fields = $wpdb->get_results( "SELECT id, name, description, type, group_id, is_required FROM {$bp->profile->table_name_fields} WHERE group_id IN ( {$group_ids_in} ) AND parent_id = 0 {$exclude_fields_sql} {$in_sql} ORDER BY field_order" );
     361
    330362                $field_ids = wp_list_pluck( $fields, 'id' );
    331363
  • trunk/tests/phpunit/testcases/members/types.php

    r9819 r10022  
    2222
    2323        /**
     24         * @dataProvider illegal_names
     25         * @ticket BP5192
     26         */
     27        public function test_illegal_names( $name ) {
     28                $this->assertWPError( bp_register_member_type( $name ) );
     29        }
     30
     31        public function illegal_names() {
     32                return array(
     33                        array( 'any' ),
     34                        array( 'null' ),
     35                        array( '_none' ),
     36                );
     37        }
     38
     39        /**
    2440         * @ticket BP6139
    2541         */
  • trunk/tests/phpunit/testcases/xprofile/class-bp-xprofile-group.php

    r10004 r10022  
    114114
    115115        /**
     116         * @group member_types
     117         * @ticket BP5192
     118         */
     119        public function test_member_type_restrictions_should_be_ignored_when_user_id_is_null_and_member_type_is_not_explicitly_provided() {
     120                $g = $this->factory->xprofile_group->create();
     121                $f = $this->factory->xprofile_field->create( array( 'field_group_id' => $g ) );
     122                bp_register_member_type( 'foo' );
     123
     124                $field = new BP_XProfile_Field( $f );
     125                $field->set_member_types( array( 'foo' ) );
     126
     127                $found_groups = BP_XProfile_Group::get( array(
     128                        'user_id' => false,
     129                        'fetch_fields' => true,
     130                ) );
     131
     132                // The groups aren't indexed, so we have to go looking for it.
     133                foreach ( $found_groups as $fg ) {
     134                        if ( $g == $fg->id ) {
     135                                $the_group = $fg;
     136                        }
     137                }
     138
     139                $this->assertContains( $f, wp_list_pluck( $the_group->fields, 'id' ) );
     140        }
     141
     142        /**
     143         * @group member_types
     144         * @ticket BP5192
     145         */
     146        public function test_member_type_restrictions_should_be_ignored_when_user_id_is_0_and_member_type_is_false() {
     147                $g = $this->factory->xprofile_group->create();
     148                $f = $this->factory->xprofile_field->create( array( 'field_group_id' => $g ) );
     149                bp_register_member_type( 'foo' );
     150
     151                $field = new BP_XProfile_Field( $f );
     152                $field->set_member_types( array( 'foo' ) );
     153
     154                $found_groups = BP_XProfile_Group::get( array(
     155                        'user_id' => 0,
     156                        'member_type' => false,
     157                        'fetch_fields' => true,
     158                ) );
     159
     160                // The groups aren't indexed, so we have to go looking for it.
     161                foreach ( $found_groups as $fg ) {
     162                        if ( $g == $fg->id ) {
     163                                $the_group = $fg;
     164                        }
     165                }
     166
     167                $this->assertContains( $f, wp_list_pluck( $the_group->fields, 'id' ) );
     168        }
     169
     170        /**
     171         * @group member_types
     172         * @ticket BP5192
     173         */
     174        public function test_member_type_restrictions_should_be_obeyed_for_nonzero_user_id() {
     175                $g = $this->factory->xprofile_group->create();
     176                $f1 = $this->factory->xprofile_field->create( array( 'field_group_id' => $g ) );
     177                $f2 = $this->factory->xprofile_field->create( array( 'field_group_id' => $g ) );
     178                $f3 = $this->factory->xprofile_field->create( array( 'field_group_id' => $g ) );
     179                $f4 = $this->factory->xprofile_field->create( array( 'field_group_id' => $g ) );
     180                bp_register_member_type( 'foo' );
     181                bp_register_member_type( 'bar' );
     182
     183                // Field 1 is visible only to 'foo' users.
     184                $field1 = new BP_XProfile_Field( $f1 );
     185                $field1->set_member_types( array( 'foo' ) );
     186
     187                // Field 2 is visible only to 'bar' users.
     188                $field2 = new BP_XProfile_Field( $f2 );
     189                $field2->set_member_types( array( 'bar' ) );
     190
     191                // Field 3 is visible to all users (no member type set).
     192
     193                // Field 4 is visible to no one.
     194                $field4 = new BP_XProfile_Field( $f4 );
     195                $field4->set_member_types( array() );
     196
     197                // User is in 'foo', so should have f1 and f3 only.
     198                $u = $this->factory->user->create();
     199                bp_set_member_type( $u, 'foo' );
     200
     201                $found_groups = BP_XProfile_Group::get( array(
     202                        'user_id' => $u,
     203                        'fetch_fields' => true,
     204                ) );
     205
     206                // The groups aren't indexed, so we have to go looking for it.
     207                foreach ( $found_groups as $fg ) {
     208                        if ( $g == $fg->id ) {
     209                                $the_group = $fg;
     210                        }
     211                }
     212
     213                $this->assertContains( $f1, wp_list_pluck( $the_group->fields, 'id' ) );
     214                $this->assertContains( $f3, wp_list_pluck( $the_group->fields, 'id' ) );
     215                $this->assertNotContains( $f2, wp_list_pluck( $the_group->fields, 'id' ) );
     216                $this->assertNotContains( $f4, wp_list_pluck( $the_group->fields, 'id' ) );
     217        }
     218
     219        /**
     220         * @group member_types
     221         * @ticket BP5192
     222         */
     223        public function test_member_type_restrictions_should_be_obeyed_for_nonzero_user_id_with_no_member_types() {
     224                $g = $this->factory->xprofile_group->create();
     225                $f1 = $this->factory->xprofile_field->create( array( 'field_group_id' => $g ) );
     226                $f2 = $this->factory->xprofile_field->create( array( 'field_group_id' => $g ) );
     227                $f3 = $this->factory->xprofile_field->create( array( 'field_group_id' => $g ) );
     228                bp_register_member_type( 'foo' );
     229                bp_register_member_type( 'bar' );
     230
     231                // Field 1 is visible only to 'foo' users.
     232                $field1 = new BP_XProfile_Field( $f1 );
     233                $field1->set_member_types( array( 'foo' ) );
     234
     235                // Field 2 is visible only to 'null' users.
     236                $field2 = new BP_XProfile_Field( $f2 );
     237                $field2->set_member_types( array( 'null' ) );
     238
     239                // Field 3 is visible to all users (no member type set).
     240
     241                // User has no member types, so should see f2 and f3 .
     242                $u = $this->factory->user->create();
     243
     244                $found_groups = BP_XProfile_Group::get( array(
     245                        'user_id' => $u,
     246                        'fetch_fields' => true,
     247                ) );
     248
     249                // The groups aren't indexed, so we have to go looking for it.
     250                foreach ( $found_groups as $fg ) {
     251                        if ( $g == $fg->id ) {
     252                                $the_group = $fg;
     253                        }
     254                }
     255
     256                $this->assertNotContains( $f1, wp_list_pluck( $the_group->fields, 'id' ) );
     257                $this->assertContains( $f2, wp_list_pluck( $the_group->fields, 'id' ) );
     258                $this->assertContains( $f3, wp_list_pluck( $the_group->fields, 'id' ) );
     259        }
     260
     261        /**
     262         * @group member_types
     263         * @ticket BP5192
     264         */
     265        public function test_member_types_of_provided_user_id_should_take_precedence_over_provided_member_type() {
     266                $g = $this->factory->xprofile_group->create();
     267                $f1 = $this->factory->xprofile_field->create( array( 'field_group_id' => $g ) );
     268                $f2 = $this->factory->xprofile_field->create( array( 'field_group_id' => $g ) );
     269                bp_register_member_type( 'foo' );
     270                bp_register_member_type( 'bar' );
     271
     272                $field1 = new BP_XProfile_Field( $f1 );
     273                $field1->set_member_types( array( 'foo' ) );
     274                $field2 = new BP_XProfile_Field( $f2 );
     275                $field2->set_member_types( array( 'bar' ) );
     276
     277                $u = $this->factory->user->create();
     278                bp_set_member_type( $u, 'foo' );
     279
     280                $found_groups = BP_XProfile_Group::get( array(
     281                        'user_id' => $u,
     282                        'member_type' => 'bar',
     283                        'fetch_fields' => true,
     284                ) );
     285
     286                // The groups aren't indexed, so we have to go looking for it.
     287                foreach ( $found_groups as $fg ) {
     288                        if ( $g == $fg->id ) {
     289                                $the_group = $fg;
     290                        }
     291                }
     292
     293                $this->assertContains( $f1, wp_list_pluck( $the_group->fields, 'id' ) );
     294        }
     295
     296        /**
     297         * @group member_types
     298         * @ticket BP5192
     299         */
     300        public function test_member_type_single_value_should_be_respected() {
     301                $g = $this->factory->xprofile_group->create();
     302                $f1 = $this->factory->xprofile_field->create( array( 'field_group_id' => $g ) );
     303                $f2 = $this->factory->xprofile_field->create( array( 'field_group_id' => $g ) );
     304                bp_register_member_type( 'foo' );
     305                bp_register_member_type( 'bar' );
     306
     307                $field1 = new BP_XProfile_Field( $f1 );
     308                $field1->set_member_types( array( 'foo' ) );
     309                $field2 = new BP_XProfile_Field( $f2 );
     310                $field2->set_member_types( array( 'bar' ) );
     311
     312                $found_groups = BP_XProfile_Group::get( array(
     313                        'member_type' => 'bar',
     314                        'fetch_fields' => true,
     315                ) );
     316
     317                // The groups aren't indexed, so we have to go looking for it.
     318                foreach ( $found_groups as $fg ) {
     319                        if ( $g == $fg->id ) {
     320                                $the_group = $fg;
     321                        }
     322                }
     323
     324                $this->assertNotContains( $f1, wp_list_pluck( $the_group->fields, 'id' ) );
     325                $this->assertContains( $f2, wp_list_pluck( $the_group->fields, 'id' ) );
     326        }
     327
     328        /**
     329         * @group member_types
     330         * @ticket BP5192
     331         */
     332        public function test_member_type_array_value_should_be_respected() {
     333                $g = $this->factory->xprofile_group->create();
     334                $f1 = $this->factory->xprofile_field->create( array( 'field_group_id' => $g ) );
     335                $f2 = $this->factory->xprofile_field->create( array( 'field_group_id' => $g ) );
     336                bp_register_member_type( 'foo' );
     337                bp_register_member_type( 'bar' );
     338
     339                $field1 = new BP_XProfile_Field( $f1 );
     340                $field1->set_member_types( array( 'foo' ) );
     341                $field2 = new BP_XProfile_Field( $f2 );
     342                $field2->set_member_types( array( 'bar' ) );
     343
     344                $found_groups = BP_XProfile_Group::get( array(
     345                        'member_type' => array( 'bar' ),
     346                        'fetch_fields' => true,
     347                ) );
     348
     349                // The groups aren't indexed, so we have to go looking for it.
     350                foreach ( $found_groups as $fg ) {
     351                        if ( $g == $fg->id ) {
     352                                $the_group = $fg;
     353                        }
     354                }
     355
     356                $this->assertNotContains( $f1, wp_list_pluck( $the_group->fields, 'id' ) );
     357                $this->assertContains( $f2, wp_list_pluck( $the_group->fields, 'id' ) );
     358        }
     359
     360        /**
     361         * @group member_types
     362         * @ticket BP5192
     363         */
     364        public function test_member_type_null_should_be_respected() {
     365                $g = $this->factory->xprofile_group->create();
     366                $f1 = $this->factory->xprofile_field->create( array( 'field_group_id' => $g ) );
     367                $f2 = $this->factory->xprofile_field->create( array( 'field_group_id' => $g ) );
     368                bp_register_member_type( 'foo' );
     369                bp_register_member_type( 'bar' );
     370
     371                $field1 = new BP_XProfile_Field( $f1 );
     372                $field1->set_member_types( array( 'foo' ) );
     373
     374                $found_groups = BP_XProfile_Group::get( array(
     375                        'member_type' => array( 'null' ),
     376                        'fetch_fields' => true,
     377                ) );
     378
     379                // The groups aren't indexed, so we have to go looking for it.
     380                foreach ( $found_groups as $fg ) {
     381                        if ( $g == $fg->id ) {
     382                                $the_group = $fg;
     383                        }
     384                }
     385
     386                $this->assertNotContains( $f1, wp_list_pluck( $the_group->fields, 'id' ) );
     387                $this->assertContains( $f2, wp_list_pluck( $the_group->fields, 'id' ) );
     388        }
     389
     390        /**
    116391         * @group save_xprofile_group_name
    117392         */
Note: See TracChangeset for help on using the changeset viewer.