Skip to:
Content

BuddyPress.org

Ticket #5192: 5192.3.diff

File 5192.3.diff, 38.2 KB (added by boonebgorges, 9 years ago)
  • src/bp-members/bp-members-functions.php

    diff --git src/bp-members/bp-members-functions.php src/bp-members/bp-members-functions.php
    index fcd8307..5d40cc4 100644
    function bp_register_member_type( $member_type, $args = array() ) { 
    25232523
    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, used to retrieve items unrestricted by 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 membe 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;
    25282544
  • src/bp-xprofile/admin/css/admin.css

    diff --git src/bp-xprofile/admin/css/admin.css src/bp-xprofile/admin/css/admin.css
    index f7374f7..a1b3170 100644
    textarea#group_description { 
    274274#bp-xprofile-add-field #post-body-content {
    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}
  • src/bp-xprofile/admin/js/admin.js

    diff --git src/bp-xprofile/admin/js/admin.js src/bp-xprofile/admin/js/admin.js
    index 31ae10c..11e9e33 100644
    function hide( id ) { 
    9696        document.getElementById( field_id ).value = '';
    9797}
    9898
     99/**
     100 * @summary Toggle "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() {
    101129                jQuery(this).width( jQuery(this).width() );
    jQuery( document ).ready( function() { 
    152180        // Set focus in Field Title, if we're on the right page
    153181        jQuery( '#bp-xprofile-add-field #title' ).focus();
    154182
     183        toggle_no_member_type_notice();
     184        jQuery( 'input.member-type-selector' ).on( 'change', function() {
     185                toggle_no_member_type_notice();
     186        } );
     187
    155188        // Set up deleting options ajax
    156189        jQuery( 'a.ajax-option-delete' ).on( 'click', function() {
    157190                var theId = this.id.split( '-' );
  • src/bp-xprofile/bp-xprofile-admin.php

    diff --git src/bp-xprofile/bp-xprofile-admin.php src/bp-xprofile/bp-xprofile-admin.php
    index 55c4b6d..3d15245 100644
    function xprofile_admin_manage_field( $group_id, $field_id = null ) { 
    361361                                        bp_update_option( 'bp-xprofile-fullname-field-name', $field->name );
    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' ) ) ) {
    366376                                        bp_xprofile_update_field_meta( $field_id, 'default_visibility', $_POST['default-visibility'] );
    function xprofile_admin_field( $admin_field, $admin_group, $class = '' ) { 
    499509                                <?php if ( empty( $field->can_delete )                                    ) : ?><?php esc_html_e( '(Primary)',  'buddypress' ); endif; ?>
    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
    504515
  • src/bp-xprofile/bp-xprofile-cache.php

    diff --git src/bp-xprofile/bp-xprofile-cache.php src/bp-xprofile/bp-xprofile-cache.php
    index 07e0ec1..a12a98e 100644
    add_action( 'xprofile_fields_saved_field', 'xprofile_clear_profile_field_objec 
    236236add_action( 'xprofile_fields_deleted_field', 'xprofile_clear_profile_field_object_cache' );
    237237
    238238/**
     239 * Clear 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' );
     247
     248/**
    239249 * Clear caches when a user's updates a field data object.
    240250 *
    241251 * @since BuddyPress (2.0.0)
  • src/bp-xprofile/bp-xprofile-template.php

    diff --git src/bp-xprofile/bp-xprofile-template.php src/bp-xprofile/bp-xprofile-template.php
    index 298b69b..c66cda4 100644
    class BP_XProfile_Data_Template { 
    153153                $r = wp_parse_args( $args, array(
    154154                        'profile_group_id'       => false,
    155155                        'user_id'                => false,
     156                        'member_type'            => 'any',
    156157                        'hide_empty_groups'      => false,
    157158                        'hide_empty_fields'      => false,
    158159                        'fetch_fields'           => false,
    function bp_has_profile( $args = '' ) { 
    333334        // Parse arguments
    334335        $r = bp_parse_args( $args, array(
    335336                'user_id'                => bp_displayed_user_id(),
     337                'member_type'            => 'any',
    336338                'profile_group_id'       => false,
    337339                'hide_empty_groups'      => true,
    338340                'hide_empty_fields'      => $hide_empty_fields_default,
  • src/bp-xprofile/classes/class-bp-xprofile-field.php

    diff --git src/bp-xprofile/classes/class-bp-xprofile-field.php src/bp-xprofile/classes/class-bp-xprofile-field.php
    index 4d08bca..9d598e3 100644
    class BP_XProfile_Field { 
    124124        public $data;
    125125
    126126        /**
     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;
     134
     135        /**
    127136         * Initialize and/or populate profile field
    128137         *
    129138         * @since BuddyPress (1.1.0)
    class BP_XProfile_Field { 
    457466                $wpdb->query( $sql );
    458467        }
    459468
     469        /**
     470         * Get the member types to which this field should be available.
     471         *
     472         * @since BuddyPress (2.4.0)
     473         */
     474        public function get_member_types() {
     475                if ( ! is_null( $this->member_types ) ) {
     476                        return $this->member_types;
     477                }
     478
     479                $raw_types = bp_xprofile_get_meta( $this->id, 'field', 'member_type', false );
     480
     481                // If `$raw_types` is not an array, it probably means this is a new field (id=0).
     482                if ( ! is_array( $raw_types ) ) {
     483                        $raw_types = array();
     484                }
     485
     486                // If '_none' is found in the array, it overrides all types.
     487                $types = array();
     488                if ( ! in_array( '_none', $raw_types ) ) {
     489                        $registered_types = bp_get_member_types();
     490
     491                        // Eliminate invalid member types saved in the database.
     492                        foreach ( $raw_types as $raw_type ) {
     493                                // 'null' is a special case - it represents users without a type.
     494                                if ( 'null' === $raw_type || isset( $registered_types[ $raw_type ] ) ) {
     495                                        $types[] = $raw_type;
     496                                }
     497                        }
     498
     499                        // If no member types have been saved, intepret as *all* member types.
     500                        if ( empty( $types ) ) {
     501                                $types = array_values( $registered_types );
     502
     503                                // + the "null" type, ie users without a type.
     504                                $types[] = 'null';
     505                        }
     506                }
     507
     508                /**
     509                 * Filters the member types to which an XProfile object should be applied.
     510                 *
     511                 * @since BuddyPress (2.4.0)
     512                 *
     513                 * @param array             $types Member types.
     514                 * @param BP_XProfile_Field $field Field object.
     515                 */
     516                $this->member_types = apply_filters( 'bp_xprofile_field_member_types', $types, $this );
     517
     518                return $this->member_types;
     519        }
     520
     521        /**
     522         * Set the member types for this field.
     523         *
     524         * @since BuddyPress (2.4.0)
     525         *
     526         * @param array $member_types Array of member types.
     527         * @param bool  $append       Whether to append to existing member types. If false, all existing member type
     528         *                            associations will be deleted before adding your `$member_types`. Default false.
     529         * @return array Member types for the current field, after being saved.
     530         */
     531        public function set_member_types( $member_types, $append = false ) {
     532                // Unset invalid member types.
     533                $types = array();
     534                foreach ( $member_types as $member_type ) {
     535                        // 'null' is a special case - it represents users without a type.
     536                        if ( 'null' === $member_type || bp_get_member_type_object( $member_type ) ) {
     537                                $types[] = $member_type;
     538                        }
     539                }
     540
     541                // When `$append` is false, delete all existing types before adding new ones.
     542                if ( ! $append ) {
     543                        bp_xprofile_delete_meta( $this->id, 'field', 'member_type' );
     544
     545                        /*
     546                         * We interpret an empty array as disassociating the field from all types. This is
     547                         * represented internally with the '_none' flag.
     548                         */
     549                        if ( empty( $types ) ) {
     550                                bp_xprofile_add_meta( $this->id, 'field', 'member_type', '_none' );
     551                        }
     552                }
     553
     554                // "All types" is represented in the database with no meta entries.
     555                $registered_types = bp_get_member_types();
     556                $rtypes = array_values( $registered_types );
     557                $rtypes[] = 'null';
     558
     559                sort( $types );
     560                sort( $rtypes );
     561
     562                if ( $types !== $rtypes ) {
     563                        // Save new types.
     564                        foreach ( $types as $type ) {
     565                                bp_xprofile_add_meta( $this->id, 'field', 'member_type', $type );
     566                        }
     567                }
     568
     569                // Reset internal cache of member types.
     570                $this->member_types = null;
     571
     572                /**
     573                 * Fires after a field's member types have been updated.
     574                 *
     575                 * @since BuddyPress (2.4.0)
     576                 *
     577                 * @param BP_XProfile_Field $field Field object.
     578                 */
     579                do_action( 'bp_xprofile_field_set_member_type', $this );
     580
     581                // Refetch fresh items from the database.
     582                return $this->get_member_types();
     583        }
     584
     585        /**
     586         * Get a label representing the field's member types.
     587         *
     588         * This is displayed alongside the field's name on the Profile Fields Dashboard panel.
     589         *
     590         * @since BuddyPress (2.4.0)
     591         *
     592         * @return string
     593         */
     594        public function get_member_type_label() {
     595                // Field 1 never gets a label.
     596                if ( 1 == $this->id ) {
     597                        return '';
     598                }
     599
     600                // Return an empty string if no member types are registered.
     601                $all_types = bp_get_member_types();
     602                if ( empty( $all_types ) ) {
     603                        return '';
     604                }
     605
     606                $member_types = $this->get_member_types();
     607
     608                // If the field applies to all member types, show no message.
     609                $all_types[] = 'null';
     610                if ( array_values( $all_types ) == $member_types ) {
     611                        return '';
     612                }
     613
     614                $label = '';
     615                if ( ! empty( $member_types ) ) {
     616                        $member_type_labels = array();
     617                        foreach ( $member_types as $member_type ) {
     618                                if ( 'null' === $member_type ) {
     619                                        $member_type_labels[] = __( 'Users with no member type', 'buddypress' );
     620                                } else {
     621                                        $mt_obj = bp_get_member_type_object( $member_type );
     622                                        $member_type_labels[] = $mt_obj->labels['name'];
     623                                }
     624                        }
     625
     626                        $label = sprintf( __( '(Member types: %s)', 'buddypress' ), implode( ', ', array_map( 'esc_html', $member_type_labels ) ) );
     627                } else {
     628                        $label = '<span class="member-type-none-notice">' . __( '(Unavailable to all member types)', 'buddypress' ) . '</span>';
     629                }
     630
     631                return $label;
     632        }
     633
    460634        /** Static Methods ********************************************************/
    461635
    462636        public static function get_type( $field_id = 0 ) {
    class BP_XProfile_Field { 
    574748        }
    575749
    576750        /**
     751         * Get the IDs of fields applicable for a given member type or array of member types.
     752         *
     753         * @todo Improved cache support.
     754         *
     755         * @since BuddyPress (2.4.0)
     756         *
     757         * @param string|array $member_types Member type or array of member types.
     758         */
     759        public static function get_fields_for_member_type( $member_types ) {
     760                global $wpdb;
     761
     762                $bp = buddypress();
     763
     764                if ( ! is_array( $member_types ) ) {
     765                        $member_types = array( $member_types );
     766                }
     767
     768                $fields = array();
     769
     770                // Pull up all recorded field member type data.
     771                $mt_meta = wp_cache_get( 'field_member_types', 'bp_xprofile' );
     772                if ( false === $mt_meta ) {
     773                        $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'" );
     774                        wp_cache_set( 'field_member_types', $mt_meta, 'bp_xprofile' );
     775                }
     776
     777                // Keep track of all fields with recorded member_type metadata.
     778                $all_recorded_field_ids = wp_list_pluck( $mt_meta, 'object_id' );
     779
     780                // Sort member_type matches in arrays, keyed by field_id.
     781                foreach ( $mt_meta as $_mt_meta ) {
     782                        if ( ! isset( $fields[ $_mt_meta->object_id ] ) ) {
     783                                $fields[ $_mt_meta->object_id ] = array();
     784                        }
     785
     786                        $fields[ $_mt_meta->object_id ][] = $_mt_meta->meta_value;
     787                }
     788
     789                // Filter out fields that don't match any passed types, or those marked _none.
     790                foreach ( $fields as $field_id => $field_types ) {
     791                        if ( ! array_intersect( $field_types, $member_types ) ) {
     792                                unset( $fields[ $field_id ] );
     793                        }
     794                }
     795
     796                // Any fields with no member_type metadata are available to all member types.
     797                if ( ! in_array( '_none', $member_types ) ) {
     798                        if ( ! empty( $all_recorded_field_ids ) ) {
     799                                $all_recorded_field_ids_sql = implode( ',', array_map( 'absint', $all_recorded_field_ids ) );
     800                                $unrestricted_field_ids = $wpdb->get_col( "SELECT id FROM {$bp->profile->table_name_fields} WHERE id NOT IN ({$all_recorded_field_ids_sql})" );
     801                        } else {
     802                                $unrestricted_field_ids = $wpdb->get_col( "SELECT id FROM {$bp->profile->table_name_fields}" );
     803                        }
     804
     805                        $all_member_types   = bp_get_member_types();
     806                        $all_member_types   = array_values( $all_member_types );
     807                        $all_member_types[] = 'null';
     808
     809                        foreach ( $unrestricted_field_ids as $unrestricted_field_id ) {
     810                                $fields[ $unrestricted_field_id ] = $all_member_types;
     811                        }
     812                }
     813
     814                return $fields;
     815        }
     816
     817        /**
    577818         * Validate form field data on sumbission
    578819         *
    579820         * @since BuddyPress (2.2.0)
    class BP_XProfile_Field { 
    718959                                                        // Output the required metabox
    719960                                                        $this->required_metabox();
    720961
     962                                                        // Output the Member Types metabox.
     963                                                        $this->member_type_metabox();
     964
    721965                                                        // Output the field visibility metaboxes
    722966                                                        $this->visibility_metabox();
    723967
    class BP_XProfile_Field { 
    8641108        }
    8651109
    8661110        /**
     1111         * Private method used to output field Member Type metabox.
     1112         *
     1113         * @since BuddyPress (2.4.0)
     1114         */
     1115        private function member_type_metabox() {
     1116
     1117                // The primary field is for all, so bail.
     1118                if ( 1 === (int) $this->id ) {
     1119                        return;
     1120                }
     1121
     1122                // Bail when no member types are registered.
     1123                if ( ! $member_types = bp_get_member_types( array(), 'objects' ) ) {
     1124                        return;
     1125                }
     1126
     1127                $field_member_types = $this->get_member_types();
     1128
     1129                ?>
     1130
     1131                <div id="member-types-div" class="postbox">
     1132                        <h3><?php _e( 'Member Types', 'buddypress' ); ?></h3>
     1133                        <div class="inside">
     1134                                <p class="description"><?php _e( 'This field should be available to:', 'buddypress' ); ?></p>
     1135
     1136                                <ul>
     1137                                        <?php foreach ( $member_types as $member_type ) : ?>
     1138                                        <li>
     1139                                                <label>
     1140                                                        <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 ) ); ?>/>
     1141                                                        <?php echo $member_type->labels['name']; ?>
     1142                                                </label>
     1143                                        </li>
     1144                                        <?php endforeach; ?>
     1145
     1146                                        <li>
     1147                                                <label>
     1148                                                        <input name="member-types[]" class="member-type-selector" type="checkbox" value="null" <?php checked( in_array( 'null', $field_member_types ) ); ?>/>
     1149                                                        <?php _e( 'Users with no member type', 'buddypress' ); ?>
     1150                                                </label>
     1151                                        </li>
     1152
     1153                                </ul>
     1154                                <p class="description member-type-none-notice<?php if ( ! empty( $field_member_types ) ) : ?> hide<?php endif; ?>"><?php _e( 'Fields with no member types are unavailable to all users.', 'buddypress' ) ?></p>
     1155                        </div>
     1156
     1157                        <input type="hidden" name="has-member-types" value="1" />
     1158                </div>
     1159
     1160                <?php
     1161        }
     1162
     1163        /**
    8671164         * Private method used to output field visibility metaboxes
    8681165         *
    8691166         * @since BuddyPress (2.3.0)
  • src/bp-xprofile/classes/class-bp-xprofile-group.php

    diff --git src/bp-xprofile/classes/class-bp-xprofile-group.php src/bp-xprofile/classes/class-bp-xprofile-group.php
    index 7d85a14..024b8df 100644
    class BP_XProfile_Group { 
    232232         *      @type int   $profile_group_id  Limit results to a single profile group.
    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.
    237242         *      @type bool  $fetch_fields      Whether to fetch each group's fields. Default: false.
    class BP_XProfile_Group { 
    251256                $r = wp_parse_args( $args, array(
    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,
    256262                        'fetch_fields'           => false,
    class BP_XProfile_Group { 
    318324                $exclude_fields_cs  = array_merge( $exclude_fields_cs, $hidden_user_fields );
    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})";
    324330                } else {
    325331                        $exclude_fields_sql = '';
    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
    332364                // Store field IDs for meta cache priming
  • tests/phpunit/testcases/members/types.php

    diff --git tests/phpunit/testcases/members/types.php tests/phpunit/testcases/members/types.php
    index 249049b..91dccd0 100644
    class BP_Tests_Members_Types extends BP_UnitTestCase { 
    2121        }
    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         */
    2642        public function test_bp_register_member_type_should_sanitize_member_type_key() {
  • new file tests/phpunit/testcases/xprofile/BP_XProfile_Field/member_types.php

    diff --git tests/phpunit/testcases/xprofile/BP_XProfile_Field/member_types.php tests/phpunit/testcases/xprofile/BP_XProfile_Field/member_types.php
    new file mode 100644
    index 0000000..6a92d4e
    - +  
     1<?php
     2
     3/**
     4 * @group member_types
     5 * @group xprofile
     6 * @ticket BP5192
     7 */
     8class BP_Tests_XProfile_BpXprofileField_MemberTypes extends BP_UnitTestCase {
     9        protected $field_group_id;
     10        protected $field_id;
     11        protected $field;
     12
     13        public function setUp() {
     14                parent::setUp();
     15                bp_register_member_type( 'foo' );
     16                bp_register_member_type( 'bar' );
     17
     18                $this->field_group_id = $this->factory->xprofile_group->create();
     19                $this->field_id = $this->factory->xprofile_field->create( array( 'field_group_id' => $this->field_group_id ) );
     20                $this->field = new BP_XProfile_Field( $this->field_id );
     21        }
     22
     23        public function tearDown() {
     24                buddypress()->members->types = array();
     25                parent::tearDown();
     26        }
     27
     28        public function test_get_single_member_type() {
     29                bp_xprofile_add_meta( $this->field_id, 'field', 'member_type', 'foo' );
     30                $this->assertEqualSets( array( 'foo' ), $this->field->get_member_types() );
     31        }
     32
     33        public function test_get_multiple_member_types() {
     34                bp_xprofile_add_meta( $this->field_id, 'field', 'member_type', 'foo' );
     35                bp_xprofile_add_meta( $this->field_id, 'field', 'member_type', 'bar' );
     36                $this->assertEqualSets( array( 'foo', 'bar' ), $this->field->get_member_types() );
     37        }
     38
     39        public function test_invalid_member_types_should_not_be_returned() {
     40                bp_xprofile_add_meta( $this->field_id, 'field', 'member_type', 'foo' );
     41                bp_xprofile_add_meta( $this->field_id, 'field', 'member_type', 'phony' );
     42                $this->assertEquals( array( 'foo' ), $this->field->get_member_types() );
     43        }
     44
     45        public function test_when_no_stored_types_are_found_all_registered_member_types_as_well_as_null_type_should_be_returned() {
     46                $this->assertEqualSets( array( 'null', 'foo', 'bar' ), $this->field->get_member_types() );
     47        }
     48
     49        public function test__none_meta_should_result_in_empty_array() {
     50                bp_xprofile_add_meta( $this->field_id, 'field', 'member_type', '_none' );
     51                $this->assertEquals( array(), $this->field->get_member_types() );
     52        }
     53
     54        public function test__none_meta_should_override_other_values() {
     55                bp_xprofile_add_meta( $this->field_id, 'field', 'member_type', '_none' );
     56                bp_xprofile_add_meta( $this->field_id, 'field', 'member_type', 'foo' );
     57                $this->assertEquals( array(), $this->field->get_member_types() );
     58        }
     59
     60        public function test_set_should_not_append_by_default() {
     61                bp_xprofile_add_meta( $this->field_id, 'field', 'member_type', 'foo' );
     62                $this->assertEquals( array( 'bar' ), $this->field->set_member_types( array( 'bar' ) ) );
     63        }
     64
     65        public function test_set_should_not_append_when_append_is_set_to_false() {
     66                bp_xprofile_add_meta( $this->field_id, 'field', 'member_type', 'foo' );
     67                $this->assertEquals( array( 'bar' ), $this->field->set_member_types( array( 'bar', false ) ) );
     68        }
     69
     70        public function test_set_should_append_when_append_is_set_to_true() {
     71                bp_xprofile_add_meta( $this->field_id, 'field', 'member_type', 'foo' );
     72                $this->assertEqualSets( array( 'foo', 'bar' ), $this->field->set_member_types( array( 'bar' ), true ) );
     73        }
     74
     75        public function test_set_empty_array_with_append_true_should_have_no_effect_on_saved_types() {
     76                bp_xprofile_add_meta( $this->field_id, 'field', 'member_type', 'foo' );
     77                $this->assertEqualSets( array( 'foo' ), $this->field->set_member_types( array(), true ) );
     78        }
     79
     80        public function test_set_empty_array_with_append_false_should_result_in_field_being_associated_with_no_member_types() {
     81                bp_xprofile_add_meta( $this->field_id, 'field', 'member_type', 'foo' );
     82                $this->assertEqualSets( array(), $this->field->set_member_types( array() ) );
     83        }
     84
     85        public function test_set_should_interpret_null_flag_properly() {
     86                $this->assertEqualSets( array( 'null' ), $this->field->set_member_types( array( 'null' ) ) );
     87        }
     88
     89        public function test_set_all_types_plus_null_should_result_in_nothing_stored_in_db() {
     90                $types = array( 'null', 'foo', 'bar' );
     91                $this->assertEqualSets( $types, $this->field->set_member_types( $types ) );
     92
     93                $types_db = bp_xprofile_get_meta( $this->field_id, 'field', 'member_type', false );
     94                $this->assertEqualSets( array(), $types_db );
     95        }
     96
     97        public function test_get_fields_for_member_type_should_get_field_with_explicit_member_type() {
     98                bp_xprofile_add_meta( $this->field_id, 'field', 'member_type', 'foo' );
     99                $found = BP_XProfile_Field::get_fields_for_member_type( 'foo' );
     100                $this->assertEqualSets( array( 1, $this->field_id ), array_keys( $found ) );
     101        }
     102
     103        public function test_get_fields_for_member_type_should_ignore_field_that_applies_to_no_member_types() {
     104                bp_xprofile_add_meta( $this->field_id, 'field', 'member_type', '_none' );
     105                $found = BP_XProfile_Field::get_fields_for_member_type( 'foo' );
     106                $this->assertEqualSets( array( 1 ), array_keys( $found ) );
     107        }
     108
     109        public function test_get_fields_for_member_type_should_ignore_field_that_applies_to_different_member_types() {
     110                bp_xprofile_add_meta( $this->field_id, 'field', 'member_type', 'bar' );
     111                $found = BP_XProfile_Field::get_fields_for_member_type( 'foo' );
     112                $this->assertEqualSets( array( 1 ), array_keys( $found ) );
     113        }
     114
     115        public function test_get_fields_for_member_type_should_include_fields_with_no_member_type_restrictions() {
     116                // A field with no member_type metadata applies to all member types.
     117                $found = BP_XProfile_Field::get_fields_for_member_type( 'foo' );
     118                $this->assertEqualSets( array( 1, $this->field_id ), array_keys( $found ) );
     119        }
     120
     121        public function test_passing_member_type_any_to_get_fields_for_member_type_should_return_unrestricted_fields() {
     122                $found = BP_XProfile_Field::get_fields_for_member_type( '' );
     123                $this->assertEqualSets( array( 1, $this->field_id ), array_keys( $found ) );
     124        }
     125
     126        public function test_passing_empty_member_type_to_get_fields_for_member_type_should_return_unrestricted_fields() {
     127                $found = BP_XProfile_Field::get_fields_for_member_type( 'any' );
     128                $this->assertEqualSets( array( 1, $this->field_id ), array_keys( $found ) );
     129        }
     130
     131        public function test_passing_member_type_none_to_get_fields_for_member_type_should_return_fields_unavailable_to_all_member_types() {
     132                bp_xprofile_add_meta( $this->field_id, 'field', 'member_type', '_none' );
     133                $found = BP_XProfile_Field::get_fields_for_member_type( '_none' );
     134                $this->assertEqualSets( array( $this->field_id ), array_keys( $found ) );
     135        }
     136
     137        public function test_get_fields_for_member_type_should_accept_an_array_of_member_types() {
     138                $f2 = $this->factory->xprofile_field->create( array( 'field_group_id' => $this->field_group_id ) );
     139                bp_xprofile_add_meta( $this->field_id, 'field', 'member_type', 'foo' );
     140                bp_xprofile_add_meta( $f2, 'field', 'member_type', 'bar' );
     141
     142                $found = BP_XProfile_Field::get_fields_for_member_type( array( 'foo', 'bar' ) );
     143                $this->assertEqualSets( array( 1, $this->field_id, $f2 ), array_keys( $found ) );
     144        }
     145
     146        /**
     147         * @group cache
     148         */
     149        public function test_get_fields_for_member_type_should_fetch_restricted_fields_from_cache() {
     150                global $wpdb;
     151
     152                $this->field->set_member_types( array( 'foo' ) );
     153
     154                // Prime cache.
     155                BP_XProfile_Field::get_fields_for_member_type( 'foo' );
     156
     157                $num_queries = $wpdb->num_queries;
     158
     159                BP_XProfile_Field::get_fields_for_member_type( 'foo' );
     160
     161                // get_fields_for_member_type() always does at least one query.
     162                $num_queries++;
     163                $this->assertSame( $num_queries, $wpdb->num_queries );
     164        }
     165
     166        /**
     167         * @group cache
     168         */
     169        public function test_get_fields_for_member_type_should_skip_cache_after_a_fields_member_type_is_modified() {
     170                global $wpdb;
     171
     172                $this->field->set_member_types( array( 'foo' ) );
     173
     174                // Prime cache.
     175                BP_XProfile_Field::get_fields_for_member_type( 'foo' );
     176
     177                $num_queries = $wpdb->num_queries;
     178
     179                $this->field->set_member_types( array( 'none' ) );
     180
     181                $found = BP_XProfile_Field::get_fields_for_member_type( 'foo' );
     182
     183                $this->assertTrue( $num_queries + 2 <= $wpdb->num_queries );
     184                $this->assertEqualSets( array( 1 ), array_keys( $found ) );
     185        }
     186}
  • tests/phpunit/testcases/xprofile/class-bp-xprofile-group.php

    diff --git tests/phpunit/testcases/xprofile/class-bp-xprofile-group.php tests/phpunit/testcases/xprofile/class-bp-xprofile-group.php
    index 6a0492b..7841b67 100644
    class BP_Tests_BP_XProfile_Group extends BP_UnitTestCase { 
    113113        }
    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         */
    118393        public function test_save_xprofile_group_name() {