Ticket #5192: 5192.4.diff
File 5192.4.diff, 42.0 KB (added by , 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..f802213 100644
function bp_register_member_type( $member_type, $args = array() ) { 2523 2523 2524 2524 $member_type = sanitize_key( $member_type ); 2525 2525 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 2526 2542 // Store the post type name as data in the object (not just as the array key). 2527 2543 $r['name'] = $member_type; 2528 2544 -
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..6dd7a20 100644
textarea#group_description { 274 274 #bp-xprofile-add-field #post-body-content { 275 275 margin-bottom: 0; 276 276 } 277 278 span.member-type-none-notice, 279 p.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..70117cd 100644
function hide( id ) { 96 96 document.getElementById( field_id ).value = ''; 97 97 } 98 98 99 /** 100 * @summary Toggles "no member type" notice. 101 * 102 * @since BuddyPress (2.4.0) 103 */ 104 function 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 99 127 var fixHelper = function(e, ui) { 100 128 ui.children().each(function() { 101 129 jQuery(this).width( jQuery(this).width() ); … … jQuery( document ).ready( function() { 152 180 // Set focus in Field Title, if we're on the right page 153 181 jQuery( '#bp-xprofile-add-field #title' ).focus(); 154 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 } ); 188 155 189 // Set up deleting options ajax 156 190 jQuery( 'a.ajax-option-delete' ).on( 'click', function() { 157 191 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 ) { 361 361 bp_update_option( 'bp-xprofile-fullname-field-name', $field->name ); 362 362 } 363 363 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 364 374 // Validate default visibility 365 375 if ( ! empty( $_POST['default-visibility'] ) && in_array( $_POST['default-visibility'], wp_list_pluck( bp_xprofile_get_visibility_levels(), 'id' ) ) ) { 366 376 bp_xprofile_update_field_meta( $field_id, 'default_visibility', $_POST['default-visibility'] ); … … function xprofile_admin_field( $admin_field, $admin_group, $class = '' ) { 499 509 <?php if ( empty( $field->can_delete ) ) : ?><?php esc_html_e( '(Primary)', 'buddypress' ); endif; ?> 500 510 <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php esc_html_e( '(Required)', 'buddypress' ); endif; ?> 501 511 <?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; ?> 502 513 503 514 <?php 504 515 -
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..8d0c5f8 100644
add_action( 'xprofile_fields_saved_field', 'xprofile_clear_profile_field_objec 236 236 add_action( 'xprofile_fields_deleted_field', 'xprofile_clear_profile_field_object_cache' ); 237 237 238 238 /** 239 * Clears member_type cache when a field's member types are updated. 240 * 241 * @since BuddyPress (2.4.0) 242 */ 243 function bp_xprofile_clear_member_type_cache() { 244 wp_cache_delete( 'field_member_types', 'bp_xprofile' ); 245 } 246 add_action( 'bp_xprofile_field_set_member_type', 'bp_xprofile_clear_member_type_cache' ); 247 248 /** 239 249 * Clear caches when a user's updates a field data object. 240 250 * 241 251 * @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 084206a..0f5672c 100644
class BP_XProfile_Data_Template { 153 153 $r = wp_parse_args( $args, array( 154 154 'profile_group_id' => false, 155 155 'user_id' => false, 156 'member_type' => 'any', 156 157 'hide_empty_groups' => false, 157 158 'hide_empty_fields' => false, 158 159 'fetch_fields' => false, … … class BP_XProfile_Data_Template { 317 318 * @param array $args { 318 319 * Array of arguments. See BP_XProfile_Group::get() for full description. Those arguments whose defaults differ 319 320 * 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. 321 * @type string|array $member_type Default: 'any'. 322 * @type bool $hide_empty_groups Default: true. 323 * @type bool $hide_empty_fields Defaults to true on the Dashboard, on a user's Edit Profile page, 324 * or during registration. Otherwise false. 325 * @type bool $fetch_visibility_level Defaults to true when an admin is viewing a profile, or when a user is 326 * viewing her own profile, or during registration. Otherwise false. 327 * @type bool $fetch_fields Default: true. 328 * @type bool $fetch_field_data Default: true. 327 329 * } 328 330 * 329 331 * @return bool … … function bp_has_profile( $args = '' ) { 345 347 // Parse arguments 346 348 $r = bp_parse_args( $args, array( 347 349 'user_id' => bp_displayed_user_id(), 350 'member_type' => 'any', 348 351 'profile_group_id' => false, 349 352 'hide_empty_groups' => true, 350 353 '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..baaac33 100644
class BP_XProfile_Field { 124 124 public $data; 125 125 126 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; 134 135 /** 127 136 * Initialize and/or populate profile field 128 137 * 129 138 * @since BuddyPress (1.1.0) … … class BP_XProfile_Field { 457 466 $wpdb->query( $sql ); 458 467 } 459 468 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 $registered_types = bp_get_member_types(); 568 $rtypes = array_values( $registered_types ); 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 460 658 /** Static Methods ********************************************************/ 461 659 462 660 public static function get_type( $field_id = 0 ) { … … class BP_XProfile_Field { 574 772 } 575 773 576 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 $bp = buddypress(); 788 789 $fields = array(); 790 791 if ( empty( $member_types ) ) { 792 $member_types = 'any'; 793 } 794 795 if ( ! is_array( $member_types ) ) { 796 $member_types = array( $member_types ); 797 } 798 799 // Pull up all recorded field member type data. 800 $mt_meta = wp_cache_get( 'field_member_types', 'bp_xprofile' ); 801 if ( false === $mt_meta ) { 802 $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'" ); 803 wp_cache_set( 'field_member_types', $mt_meta, 'bp_xprofile' ); 804 } 805 806 // Keep track of all fields with recorded member_type metadata. 807 $all_recorded_field_ids = wp_list_pluck( $mt_meta, 'object_id' ); 808 809 // Sort member_type matches in arrays, keyed by field_id. 810 foreach ( $mt_meta as $_mt_meta ) { 811 if ( ! isset( $fields[ $_mt_meta->object_id ] ) ) { 812 $fields[ $_mt_meta->object_id ] = array(); 813 } 814 815 $fields[ $_mt_meta->object_id ][] = $_mt_meta->meta_value; 816 } 817 818 /* 819 * Filter out fields that don't match any passed types, or those marked _none. 820 * The 'any' type is implicitly handled here: it will match no types. 821 */ 822 foreach ( $fields as $field_id => $field_types ) { 823 if ( ! array_intersect( $field_types, $member_types ) ) { 824 unset( $fields[ $field_id ] ); 825 } 826 } 827 828 // Any fields with no member_type metadata are available to all member types. 829 if ( ! in_array( '_none', $member_types ) ) { 830 if ( ! empty( $all_recorded_field_ids ) ) { 831 $all_recorded_field_ids_sql = implode( ',', array_map( 'absint', $all_recorded_field_ids ) ); 832 $unrestricted_field_ids = $wpdb->get_col( "SELECT id FROM {$bp->profile->table_name_fields} WHERE id NOT IN ({$all_recorded_field_ids_sql})" ); 833 } else { 834 $unrestricted_field_ids = $wpdb->get_col( "SELECT id FROM {$bp->profile->table_name_fields}" ); 835 } 836 837 // Append the 'null' pseudo-type. 838 $all_member_types = bp_get_member_types(); 839 $all_member_types = array_values( $all_member_types ); 840 $all_member_types[] = 'null'; 841 842 foreach ( $unrestricted_field_ids as $unrestricted_field_id ) { 843 $fields[ $unrestricted_field_id ] = $all_member_types; 844 } 845 } 846 847 return $fields; 848 } 849 850 /** 577 851 * Validate form field data on sumbission 578 852 * 579 853 * @since BuddyPress (2.2.0) … … class BP_XProfile_Field { 718 992 // Output the required metabox 719 993 $this->required_metabox(); 720 994 995 // Output the Member Types metabox. 996 $this->member_type_metabox(); 997 721 998 // Output the field visibility metaboxes 722 999 $this->visibility_metabox(); 723 1000 … … class BP_XProfile_Field { 864 1141 } 865 1142 866 1143 /** 1144 * Private method used to output field Member Type metabox. 1145 * 1146 * @since BuddyPress (2.4.0) 1147 */ 1148 private function member_type_metabox() { 1149 1150 // The primary field is for all, so bail. 1151 if ( 1 === (int) $this->id ) { 1152 return; 1153 } 1154 1155 // Bail when no member types are registered. 1156 if ( ! $member_types = bp_get_member_types( array(), 'objects' ) ) { 1157 return; 1158 } 1159 1160 $field_member_types = $this->get_member_types(); 1161 1162 ?> 1163 1164 <div id="member-types-div" class="postbox"> 1165 <h3><?php _e( 'Member Types', 'buddypress' ); ?></h3> 1166 <div class="inside"> 1167 <p class="description"><?php _e( 'This field should be available to:', 'buddypress' ); ?></p> 1168 1169 <ul> 1170 <?php foreach ( $member_types as $member_type ) : ?> 1171 <li> 1172 <label> 1173 <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 ) ); ?>/> 1174 <?php echo $member_type->labels['name']; ?> 1175 </label> 1176 </li> 1177 <?php endforeach; ?> 1178 1179 <li> 1180 <label> 1181 <input name="member-types[]" class="member-type-selector" type="checkbox" value="null" <?php checked( in_array( 'null', $field_member_types ) ); ?>/> 1182 <?php _e( 'Users with no member type', 'buddypress' ); ?> 1183 </label> 1184 </li> 1185 1186 </ul> 1187 <p class="description member-type-none-notice<?php if ( ! empty( $field_member_types ) ) : ?> hide<?php endif; ?>"><?php _e( 'Unavailable to all members.', 'buddypress' ) ?></p> 1188 </div> 1189 1190 <input type="hidden" name="has-member-types" value="1" /> 1191 </div> 1192 1193 <?php 1194 } 1195 1196 /** 867 1197 * Private method used to output field visibility metaboxes 868 1198 * 869 1199 * @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 { 232 232 * @type int $profile_group_id Limit results to a single profile group. 233 233 * @type int $user_id Required if you want to load a specific user's data. 234 234 * 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. 235 240 * @type bool $hide_empty_groups True to hide groups that don't have any fields. Default: false. 236 241 * @type bool $hide_empty_fields True to hide fields where the user has not provided data. Default: false. 237 242 * @type bool $fetch_fields Whether to fetch each group's fields. Default: false. … … class BP_XProfile_Group { 251 256 $r = wp_parse_args( $args, array( 252 257 'profile_group_id' => false, 253 258 'user_id' => bp_displayed_user_id(), 259 'member_type' => false, 254 260 'hide_empty_groups' => false, 255 261 'hide_empty_fields' => false, 256 262 'fetch_fields' => false, … … class BP_XProfile_Group { 318 324 $exclude_fields_cs = array_merge( $exclude_fields_cs, $hidden_user_fields ); 319 325 $exclude_fields_cs = implode( ',', $exclude_fields_cs ); 320 326 321 // Set up IN query for field IDs327 // Set up NOT IN query for excluded field IDs. 322 328 if ( ! empty( $exclude_fields_cs ) ) { 323 329 $exclude_fields_sql = "AND id NOT IN ({$exclude_fields_cs})"; 324 330 } else { 325 331 $exclude_fields_sql = ''; 326 332 } 327 333 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 328 359 // 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 330 362 $field_ids = wp_list_pluck( $fields, 'id' ); 331 363 332 364 // 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 { 21 21 } 22 22 23 23 /** 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 /** 24 40 * @ticket BP6139 25 41 */ 26 42 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..96aa3ac
- + 1 <?php 2 3 /** 4 * @group member_types 5 * @group xprofile 6 * @ticket BP5192 7 */ 8 class 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 $f2 = $this->factory->xprofile_field->create( array( 'field_group_id' => $this->field_group_id ) ); 123 124 $field_2 = new BP_XProfile_Field( $f2 ); 125 $field_2->set_member_types( array( 'foo' ) ); 126 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_empty_member_type_to_get_fields_for_member_type_should_return_unrestricted_fields() { 132 $f2 = $this->factory->xprofile_field->create( array( 'field_group_id' => $this->field_group_id ) ); 133 134 $field_2 = new BP_XProfile_Field( $f2 ); 135 $field_2->set_member_types( array( 'foo' ) ); 136 137 $found = BP_XProfile_Field::get_fields_for_member_type( '' ); 138 $this->assertEqualSets( array( 1, $this->field_id ), array_keys( $found ) ); 139 } 140 141 public function test_passing_member_type_none_to_get_fields_for_member_type_should_return_fields_unavailable_to_all_member_types() { 142 bp_xprofile_add_meta( $this->field_id, 'field', 'member_type', '_none' ); 143 $found = BP_XProfile_Field::get_fields_for_member_type( '_none' ); 144 $this->assertEqualSets( array( $this->field_id ), array_keys( $found ) ); 145 } 146 147 public function test_get_fields_for_member_type_should_accept_an_array_of_member_types() { 148 $f2 = $this->factory->xprofile_field->create( array( 'field_group_id' => $this->field_group_id ) ); 149 bp_xprofile_add_meta( $this->field_id, 'field', 'member_type', 'foo' ); 150 bp_xprofile_add_meta( $f2, 'field', 'member_type', 'bar' ); 151 152 $found = BP_XProfile_Field::get_fields_for_member_type( array( 'foo', 'bar' ) ); 153 $this->assertEqualSets( array( 1, $this->field_id, $f2 ), array_keys( $found ) ); 154 } 155 156 /** 157 * @group cache 158 */ 159 public function test_get_fields_for_member_type_should_fetch_restricted_fields_from_cache() { 160 global $wpdb; 161 162 $this->field->set_member_types( array( 'foo' ) ); 163 164 // Prime cache. 165 BP_XProfile_Field::get_fields_for_member_type( 'foo' ); 166 167 $num_queries = $wpdb->num_queries; 168 169 BP_XProfile_Field::get_fields_for_member_type( 'foo' ); 170 171 // get_fields_for_member_type() always does at least one query. 172 $num_queries++; 173 $this->assertSame( $num_queries, $wpdb->num_queries ); 174 } 175 176 /** 177 * @group cache 178 */ 179 public function test_get_fields_for_member_type_should_skip_cache_after_a_fields_member_type_is_modified() { 180 global $wpdb; 181 182 $this->field->set_member_types( array( 'foo' ) ); 183 184 // Prime cache. 185 BP_XProfile_Field::get_fields_for_member_type( 'foo' ); 186 187 $num_queries = $wpdb->num_queries; 188 189 $this->field->set_member_types( array( 'none' ) ); 190 191 $found = BP_XProfile_Field::get_fields_for_member_type( 'foo' ); 192 193 $this->assertTrue( $num_queries + 2 <= $wpdb->num_queries ); 194 $this->assertEqualSets( array( 1 ), array_keys( $found ) ); 195 } 196 197 public function test_get_member_type_label_order() { 198 // Should be alphabetical, with the null option last. 199 bp_register_member_type( 'aaa', array( 200 'labels' => array( 201 'name' => 'AAA', 202 ), 203 ) ); 204 bp_register_member_type( 'zzz', array( 205 'labels' => array( 206 'name' => 'ZZZ', 207 ), 208 ) ); 209 210 $this->field->set_member_types( array( 'aaa', 'zzz', 'null' ) ); 211 212 $expected = '(Member types: AAA, ZZZ, Users with no member type)'; 213 $this->assertSame( $expected, $this->field->get_member_type_label() ); 214 } 215 } -
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 { 113 113 } 114 114 115 115 /** 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 /** 116 391 * @group save_xprofile_group_name 117 392 */ 118 393 public function test_save_xprofile_group_name() {