Skip to:
Content

BuddyPress.org

Changeset 10022


Ignore:
Timestamp:
07/21/2015 02:00:38 PM (9 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.