Ticket #5220: 5220.01.patch
File 5220.01.patch, 120.9 KB (added by , 11 years ago) |
---|
-
bp-members/admin/css/admin.css
diff --git bp-members/admin/css/admin.css bp-members/admin/css/admin.css index 5473fe5..5d295da 100644
div#profile-page.wrap form#your-profile ul#profile-nav { 15 15 width:100%; 16 16 } 17 17 18 div#community-profile-page h2:first-of-type {19 margin-bottom:1em;20 }21 22 div#community-profile-page h2.profile-section {23 border-bottom:dotted 1px #ccc;24 }25 26 18 div#community-profile-page ul#profile-nav { 27 19 border-bottom:solid 1px #ccc; 28 20 width:100%; … … div#community-profile-page p.not-activated { 104 96 color:red; 105 97 } 106 98 107 div#community-profile-page .form-table td.admin-field-visibility-td{108 padding:5px 5px 15px 5px;99 .alt { 100 background: none; 109 101 } 110 111 div#community-profile-page .form-table tr.admin-field-visibility-tr { 112 border-bottom:dotted 1px #ccc; 102 .bp-profile-field { 103 border-bottom: dotted 1px #ccc; 104 font-size: 14px; 105 margin: 15px 0; 113 106 } 114 115 div#community-profile-page .form-table tr.admin-field-visibility-tr:last-child{ 116 border:none; 107 .bp-profile-field:last-child { 108 border-bottom: 0; 117 109 } 118 119 div#community-profile-page .field-visibility-settings legend, 120 div#community-profile-page .field-visibility-settings-notoggle { 110 .bp-profile-field p { 121 111 font-size: 14px; 122 font-style: italic;123 color:#666;124 112 } 125 126 div#community-profile-page .field-visibility-settings ul { 127 margin:0; 128 font-size: 13px; 113 .bp-profile-field .datebox > label, 114 .bp-profile-field .radio > label, 115 .bp-profile-field > label { /* label takes on left side 200px */ 116 display: inline-block; 117 font-weight: 600; 118 text-align: left; 119 vertical-align: middle; 120 width: 200px; 129 121 } 130 122 131 div#community-profile-page .field-visibility-settings ul li { 132 display:inline-block; 133 margin-right:1em; 123 .field_type_textarea > label, 124 .field_type_multiselectbox > label, 125 .field_type_radio .radio > label, 126 .field_type_checkbox .checkbox > label { /* these fields are usually pretty tall, so align the label for better consistency */ 127 vertical-align: top; 134 128 } 135 136 div#community-profile-page .form-table td.admin-field-radio label, 137 div#community-profile-page .form-table td.admin-field-checkbox label { 138 display:block; 129 .bp-profile-field .description { /* description also sits in the right side column */ 130 margin: 10px 0 10px 200px; 131 text-align: left; 139 132 } 140 141 .field-visibility-settings { 133 .clear-value { /* 'clear value' option also sits in the right side column */ 134 display: block; 135 font-size: 12px; 136 margin-left: 200px; 137 } 138 .field_type_checkbox .checkbox > label + label { /* force checkboxes to new lines, in the right side column */ 139 display: block; 140 margin-left: 200px; 141 width: auto; 142 } 143 .field_type_radio .radio div:not(.field-visibility-settings) label { /* force radio buttons to new lines */ 144 display: block; 145 } 146 .field_type_radio .radio div:not(.field-visibility-settings) { /* make the radio buttons sit in the right side column */ 147 display: inline-block; 148 } 149 .field-visibility-settings-notoggle, 150 .field-visibility-settings-toggle { /* visibility settings go in the left column */ 151 margin: 10px 0 10px 200px; 152 text-align: left; 153 } 154 .field-visibility-settings { /* visibility settings go in the left column */ 142 155 display: none; 143 } 144 No newline at end of file 156 margin-left: 200px; 157 } 158 .field-visibility-settings .button { /* visibility setting close button */ 159 margin-bottom: 15px; 160 } 161 #normal-sortables .field-visibility-settings legend { /* id required for css selector weight */ 162 font-size: 16px; 163 margin-bottom: 10px; 164 } -
bp-templates/bp-legacy/buddypress/members/register.php
diff --git bp-templates/bp-legacy/buddypress/members/register.php bp-templates/bp-legacy/buddypress/members/register.php index 8679dc2..6624817 100644
68 68 69 69 <div class="editfield"> 70 70 71 <?php if ( 'textbox' == bp_get_the_profile_field_type() ) : ?> 71 <?php 72 $field_type = bp_xprofile_create_field_type( bp_get_the_profile_field_type() ); 73 $field_type->edit_field_html(); 72 74 73 <label for="<?php bp_the_profile_field_input_name(); ?>"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php _e( '(required)', 'buddypress' ); ?><?php endif; ?></label> 74 <?php do_action( bp_get_the_profile_field_errors_action() ); ?> 75 <input type="text" name="<?php bp_the_profile_field_input_name(); ?>" id="<?php bp_the_profile_field_input_name(); ?>" value="<?php bp_the_profile_field_edit_value(); ?>" /> 75 do_action( 'bp_custom_profile_edit_fields_pre_visibility' ); 76 76 77 <?php endif; ?> 78 79 <?php if ( 'textarea' == bp_get_the_profile_field_type() ) : ?> 80 81 <label for="<?php bp_the_profile_field_input_name(); ?>"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php _e( '(required)', 'buddypress' ); ?><?php endif; ?></label> 82 <?php do_action( bp_get_the_profile_field_errors_action() ); ?> 83 <textarea rows="5" cols="40" name="<?php bp_the_profile_field_input_name(); ?>" id="<?php bp_the_profile_field_input_name(); ?>"><?php bp_the_profile_field_edit_value(); ?></textarea> 84 85 <?php endif; ?> 86 87 <?php if ( 'selectbox' == bp_get_the_profile_field_type() ) : ?> 88 89 <label for="<?php bp_the_profile_field_input_name(); ?>"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php _e( '(required)', 'buddypress' ); ?><?php endif; ?></label> 90 <?php do_action( bp_get_the_profile_field_errors_action() ); ?> 91 <select name="<?php bp_the_profile_field_input_name(); ?>" id="<?php bp_the_profile_field_input_name(); ?>"> 92 <?php bp_the_profile_field_options(); ?> 93 </select> 94 95 <?php endif; ?> 96 97 <?php if ( 'multiselectbox' == bp_get_the_profile_field_type() ) : ?> 98 99 <label for="<?php bp_the_profile_field_input_name(); ?>"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php _e( '(required)', 'buddypress' ); ?><?php endif; ?></label> 100 <?php do_action( bp_get_the_profile_field_errors_action() ); ?> 101 <select name="<?php bp_the_profile_field_input_name(); ?>" id="<?php bp_the_profile_field_input_name(); ?>" multiple="multiple"> 102 <?php bp_the_profile_field_options(); ?> 103 </select> 104 105 <?php endif; ?> 106 107 <?php if ( 'radio' == bp_get_the_profile_field_type() ) : ?> 108 109 <div class="radio"> 110 <span class="label"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php _e( '(required)', 'buddypress' ); ?><?php endif; ?></span> 111 112 <?php do_action( bp_get_the_profile_field_errors_action() ); ?> 113 <?php bp_the_profile_field_options(); ?> 114 115 <?php if ( !bp_get_the_profile_field_is_required() ) : ?> 116 <a class="clear-value" href="javascript:clear( '<?php bp_the_profile_field_input_name(); ?>' );"><?php _e( 'Clear', 'buddypress' ); ?></a> 117 <?php endif; ?> 118 </div> 119 120 <?php endif; ?> 121 122 <?php if ( 'checkbox' == bp_get_the_profile_field_type() ) : ?> 123 124 <div class="checkbox"> 125 <span class="label"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php _e( '(required)', 'buddypress' ); ?><?php endif; ?></span> 126 127 <?php do_action( bp_get_the_profile_field_errors_action() ); ?> 128 <?php bp_the_profile_field_options(); ?> 129 </div> 130 131 <?php endif; ?> 132 133 <?php if ( 'datebox' == bp_get_the_profile_field_type() ) : ?> 134 135 <div class="datebox"> 136 <label for="<?php bp_the_profile_field_input_name(); ?>_day"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php _e( '(required)', 'buddypress' ); ?><?php endif; ?></label> 137 <?php do_action( bp_get_the_profile_field_errors_action() ); ?> 138 139 <select name="<?php bp_the_profile_field_input_name(); ?>_day" id="<?php bp_the_profile_field_input_name(); ?>_day"> 140 <?php bp_the_profile_field_options( 'type=day' ); ?> 141 </select> 142 143 <select name="<?php bp_the_profile_field_input_name(); ?>_month" id="<?php bp_the_profile_field_input_name(); ?>_month"> 144 <?php bp_the_profile_field_options( 'type=month' ); ?> 145 </select> 146 147 <select name="<?php bp_the_profile_field_input_name(); ?>_year" id="<?php bp_the_profile_field_input_name(); ?>_year"> 148 <?php bp_the_profile_field_options( 'type=year' ); ?> 149 </select> 150 </div> 151 152 <?php endif; ?> 153 154 <?php do_action( 'bp_custom_profile_edit_fields_pre_visibility' ); ?> 155 156 <?php if ( bp_current_user_can( 'bp_xprofile_change_field_visibility' ) ) : ?> 77 if ( bp_current_user_can( 'bp_xprofile_change_field_visibility' ) ) : ?> 157 78 <p class="field-visibility-settings-toggle" id="field-visibility-settings-toggle-<?php bp_the_profile_field_id() ?>"> 158 79 <?php printf( __( 'This field can be seen by: <span class="current-visibility-level">%s</span>', 'buddypress' ), bp_get_the_profile_field_visibility_level_label() ) ?> <a href="#" class="visibility-toggle-link"><?php _ex( 'Change', 'Change profile field visibility level', 'buddypress' ); ?></a> 159 80 </p> -
bp-templates/bp-legacy/buddypress/members/single/profile/edit.php
diff --git bp-templates/bp-legacy/buddypress/members/single/profile/edit.php bp-templates/bp-legacy/buddypress/members/single/profile/edit.php index b7b6cc5..a20c079 100644
if ( bp_has_profile( 'profile_group_id=' . bp_get_current_profile_group_id() ) ) 21 21 22 22 <div<?php bp_field_css_class( 'editfield' ); ?>> 23 23 24 <?php if ( 'textbox' == bp_get_the_profile_field_type() ) : ?> 24 <?php 25 $field_type = bp_xprofile_create_field_type( bp_get_the_profile_field_type() ); 26 $field_type->edit_field_html(); 25 27 26 <label for="<?php bp_the_profile_field_input_name(); ?>"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php _e( '(required)', 'buddypress' ); ?><?php endif; ?></label> 27 <input type="text" name="<?php bp_the_profile_field_input_name(); ?>" id="<?php bp_the_profile_field_input_name(); ?>" value="<?php bp_the_profile_field_edit_value(); ?>" <?php if ( bp_get_the_profile_field_is_required() ) : ?>aria-required="true"<?php endif; ?>/> 28 29 <?php endif; ?> 30 31 <?php if ( 'textarea' == bp_get_the_profile_field_type() ) : ?> 32 33 <label for="<?php bp_the_profile_field_input_name(); ?>"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php _e( '(required)', 'buddypress' ); ?><?php endif; ?></label> 34 <textarea rows="5" cols="40" name="<?php bp_the_profile_field_input_name(); ?>" id="<?php bp_the_profile_field_input_name(); ?>" <?php if ( bp_get_the_profile_field_is_required() ) : ?>aria-required="true"<?php endif; ?>><?php bp_the_profile_field_edit_value(); ?></textarea> 35 36 <?php endif; ?> 37 38 <?php if ( 'selectbox' == bp_get_the_profile_field_type() ) : ?> 39 40 <label for="<?php bp_the_profile_field_input_name(); ?>"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php _e( '(required)', 'buddypress' ); ?><?php endif; ?></label> 41 <select name="<?php bp_the_profile_field_input_name(); ?>" id="<?php bp_the_profile_field_input_name(); ?>" <?php if ( bp_get_the_profile_field_is_required() ) : ?>aria-required="true"<?php endif; ?>> 42 <?php bp_the_profile_field_options(); ?> 43 </select> 44 45 <?php endif; ?> 46 47 <?php if ( 'multiselectbox' == bp_get_the_profile_field_type() ) : ?> 48 49 <label for="<?php bp_the_profile_field_input_name(); ?>"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php _e( '(required)', 'buddypress' ); ?><?php endif; ?></label> 50 <select name="<?php bp_the_profile_field_input_name(); ?>" id="<?php bp_the_profile_field_input_name(); ?>" multiple="multiple" <?php if ( bp_get_the_profile_field_is_required() ) : ?>aria-required="true"<?php endif; ?>> 51 52 <?php bp_the_profile_field_options(); ?> 53 54 </select> 55 56 <?php if ( !bp_get_the_profile_field_is_required() ) : ?> 57 58 <a class="clear-value" href="javascript:clear( '<?php bp_the_profile_field_input_name(); ?>' );"><?php _e( 'Clear', 'buddypress' ); ?></a> 59 60 <?php endif; ?> 61 62 <?php endif; ?> 63 64 <?php if ( 'radio' == bp_get_the_profile_field_type() ) : ?> 65 66 <div class="radio"> 67 <span class="label"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php _e( '(required)', 'buddypress' ); ?><?php endif; ?></span> 68 69 <?php bp_the_profile_field_options(); ?> 70 71 <?php if ( !bp_get_the_profile_field_is_required() ) : ?> 72 73 <a class="clear-value" href="javascript:clear( '<?php bp_the_profile_field_input_name(); ?>' );"><?php _e( 'Clear', 'buddypress' ); ?></a> 74 75 <?php endif; ?> 76 </div> 77 78 <?php endif; ?> 79 80 <?php if ( 'checkbox' == bp_get_the_profile_field_type() ) : ?> 81 82 <div class="checkbox"> 83 <span class="label"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php _e( '(required)', 'buddypress' ); ?><?php endif; ?></span> 84 85 <?php bp_the_profile_field_options(); ?> 86 </div> 87 88 <?php endif; ?> 89 90 <?php if ( 'datebox' == bp_get_the_profile_field_type() ) : ?> 91 92 <div class="datebox"> 93 <label for="<?php bp_the_profile_field_input_name(); ?>_day"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php _e( '(required)', 'buddypress' ); ?><?php endif; ?></label> 94 95 <select name="<?php bp_the_profile_field_input_name(); ?>_day" id="<?php bp_the_profile_field_input_name(); ?>_day" <?php if ( bp_get_the_profile_field_is_required() ) : ?>aria-required="true"<?php endif; ?>> 96 97 <?php bp_the_profile_field_options( 'type=day' ); ?> 98 99 </select> 100 101 <select name="<?php bp_the_profile_field_input_name(); ?>_month" id="<?php bp_the_profile_field_input_name(); ?>_month" <?php if ( bp_get_the_profile_field_is_required() ) : ?>aria-required="true"<?php endif; ?>> 102 103 <?php bp_the_profile_field_options( 'type=month' ); ?> 104 105 </select> 106 107 <select name="<?php bp_the_profile_field_input_name(); ?>_year" id="<?php bp_the_profile_field_input_name(); ?>_year" <?php if ( bp_get_the_profile_field_is_required() ) : ?>aria-required="true"<?php endif; ?>> 108 109 <?php bp_the_profile_field_options( 'type=year' ); ?> 110 111 </select> 112 </div> 113 114 <?php endif; ?> 115 116 <?php do_action( 'bp_custom_profile_edit_fields_pre_visibility' ); ?> 28 do_action( 'bp_custom_profile_edit_fields_pre_visibility' ); 29 ?> 117 30 118 31 <?php if ( bp_current_user_can( 'bp_xprofile_change_field_visibility' ) ) : ?> 119 32 <p class="field-visibility-settings-toggle" id="field-visibility-settings-toggle-<?php bp_the_profile_field_id() ?>"> -
bp-templates/bp-legacy/css/buddypress.css
diff --git bp-templates/bp-legacy/css/buddypress.css bp-templates/bp-legacy/css/buddypress.css index 6c13c70..b16f39b 100644
body.activity-permalink #buddypress div.activity-comments div.acomment-content { 607 607 font-weight: bold; 608 608 margin: 15px 0 5px 0; 609 609 } 610 #buddypress .standard-form div.checkbox label ,611 #buddypress .standard-form div.radio label {610 #buddypress .standard-form div.checkbox label:nth-child(n+2), 611 #buddypress .standard-form div.radio div label { 612 612 color: #888; 613 613 font-size: 100%; 614 614 font-weight: normal; -
bp-xprofile/bp-xprofile-admin.php
diff --git bp-xprofile/bp-xprofile-admin.php bp-xprofile/bp-xprofile-admin.php index 99dcfd8..10681ab 100644
function xprofile_admin_field( $admin_field, $admin_group, $class = '' ) { 382 382 <legend><span><?php bp_the_profile_field_name(); ?> <?php if( !$field->can_delete ) : ?> <?php _e( '(Primary)', 'buddypress' ); endif; ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php _e( '(Required)', 'buddypress' ) ?><?php endif; ?></span></legend> 383 383 <div class="field-wrapper"> 384 384 385 <?php switch ( $field->type ) : case 'textbox' : ?> 386 387 <input type="text" name="<?php bp_the_profile_field_input_name() ?>" id="<?php bp_the_profile_field_input_name() ?>" value="" /> 388 389 <?php break; case 'textarea' : ?> 390 391 <textarea rows="5" cols="40" name="<?php bp_the_profile_field_input_name() ?>" id="<?php bp_the_profile_field_input_name() ?>"></textarea> 392 393 <?php break; case 'selectbox' : ?> 394 395 <select name="<?php bp_the_profile_field_input_name() ?>" id="<?php bp_the_profile_field_input_name() ?>"> 396 397 <?php bp_the_profile_field_options() ?> 398 399 </select> 400 401 <?php break; case 'multiselectbox' : ?> 402 403 <select name="<?php bp_the_profile_field_input_name() ?>" id="<?php bp_the_profile_field_input_name() ?>" multiple="multiple"> 404 405 <?php bp_the_profile_field_options() ?> 406 407 </select> 408 409 <?php break; case 'radio' : ?> 410 411 <?php bp_the_profile_field_options() ?> 412 413 <?php if ( !bp_get_the_profile_field_is_required() ) : ?> 414 415 <a class="clear-value" href="javascript:clear( '<?php bp_the_profile_field_input_name() ?>' );"><?php _e( 'Clear', 'buddypress' ) ?></a> 416 417 <?php endif; ?> 418 419 <?php break; case 'checkbox' : ?> 420 421 <?php bp_the_profile_field_options(); ?> 422 423 <?php break; case 'datebox' : ?> 424 425 <select name="<?php bp_the_profile_field_input_name(); ?>_day" id="<?php bp_the_profile_field_input_name(); ?>_day"> 426 427 <?php bp_the_profile_field_options( 'type=day' ); ?> 428 429 </select> 430 431 <select name="<?php bp_the_profile_field_input_name(); ?>_month" id="<?php bp_the_profile_field_input_name(); ?>_month"> 432 433 <?php bp_the_profile_field_options( 'type=month' ); ?> 434 435 </select> 436 437 <select name="<?php bp_the_profile_field_input_name(); ?>_year" id="<?php bp_the_profile_field_input_name(); ?>_year"> 438 439 <?php bp_the_profile_field_options( 'type=year' ); ?> 440 441 </select> 442 443 <?php break; default : ?> 444 445 <?php do_action( 'xprofile_admin_field', $field, 1 ); ?> 385 <?php 386 $field_type = bp_xprofile_create_field_type( $field->type ); 387 $field_type->admin_field_html(); 446 388 447 <?php endswitch; ?> 389 do_action( 'xprofile_admin_field', $field, 1 ); 390 ?> 448 391 449 392 <?php if ( $field->description ) : ?> 450 393 … … function xprofile_admin_field( $admin_field, $admin_group, $class = '' ) { 467 410 <?php 468 411 } 469 412 413 /** 414 * Print <option> elements containing the xprofile field types. 415 * 416 * @param string $select_field_type The name of the field type that should be selected. Will defaults to "textbox" if NULL is passed. 417 * @since BuddyPress (2.0.0) 418 */ 419 function bp_xprofile_admin_form_field_types( $select_field_type ) { 420 $categories = array(); 421 422 if ( is_null( $select_field_type ) ) { 423 $select_field_type = 'textbox'; 424 } 425 426 // Sort each field type into its category 427 foreach ( bp_xprofile_get_field_types() as $field_name => $field_class ) { 428 $field_type_obj = new $field_class; 429 $the_category = $field_type_obj->category; 430 431 // Fallback to a catch-all if category not set 432 if ( ! $the_category ) { 433 $the_category = _x( 'Other', 'xprofile field type category', 'buddypress' ); 434 } 435 436 if ( isset( $categories[$the_category] ) ) { 437 $categories[$the_category][] = array( $field_name, $field_type_obj ); 438 } else { 439 $categories[$the_category] = array( array( $field_name, $field_type_obj ) ); 440 } 441 } 442 443 // Sort the categories alphabetically. ksort()'s SORT_NATURAL is only in PHP >= 5.4 :(( 444 uksort( $categories, 'strnatcmp' ); 445 446 // Loop through each category and output form <options> 447 foreach ( $categories as $category => $fields ) { 448 printf( '<optgroup label="%1$s">', esc_attr( $category ) ); // Already i18n'd in each profile type class 449 450 // Sort these fields types alphabetically 451 uasort( $fields, create_function( '$a, $b', 'return strnatcmp( $a[1]->name, $b[1]->name );' ) ); 452 453 foreach ( $fields as $field_type_obj ) { 454 $field_name = $field_type_obj[0]; 455 $field_type_obj = $field_type_obj[1]; 456 457 printf( '<option value="%1$s" %2$s>%3$s</option>', esc_attr( $field_name ), selected( $select_field_type, $field_name, false ), esc_html( $field_type_obj->name ) ); 458 } 459 460 printf( '</optgroup>' ); 461 } 462 } 463 470 464 if ( ! class_exists( 'BP_XProfile_User_Admin' ) ) : 471 465 /** 472 466 * Load xProfile Profile admin area. … … class BP_XProfile_User_Admin { 633 627 // Set the errors var 634 628 $errors = false; 635 629 636 // Now we've checked for required fields, let s save the values.630 // Now we've checked for required fields, let's save the values. 637 631 foreach ( (array) $posted_field_ids as $field_id ) { 638 632 639 633 // Certain types of fields (checkboxes, multiselects) may come through empty. Save them as an empty array so that they don't get overwritten by the default on the next edit. … … class BP_XProfile_User_Admin { 693 687 } 694 688 695 689 if ( bp_has_profile( $r ) ) : 696 697 690 while ( bp_profile_groups() ) : bp_the_profile_group(); ?> 691 <input type="hidden" name="field_ids" id="<?php echo esc_attr( 'field_ids_' . bp_get_the_profile_group_slug() ); ?>" value="<?php echo esc_attr( bp_get_the_profile_group_field_ids() ); ?>" /> 698 692 699 <p class="description"><?php bp_the_profile_group_description(); ?></p> 700 701 <table class="form-table"> 702 <tbody> 703 704 <?php while ( bp_profile_fields() ) : bp_the_profile_field(); ?> 705 706 <tr> 707 708 <?php if ( 'textbox' === bp_get_the_profile_field_type() ) : ?> 693 <?php if ( bp_get_the_profile_group_description() ) : ?> 694 <p class="description"><?php bp_the_profile_group_description(); ?></p> 695 <?php 696 endif; 709 697 710 <th><label for="<?php bp_the_profile_field_input_name(); ?>"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php _e( '(required)', 'buddypress' ); ?><?php endif; ?></label></th> 711 <td class="admin-field-<?php bp_the_profile_field_type();?>"> 712 <input type="text" name="<?php bp_the_profile_field_input_name(); ?>" id="<?php bp_the_profile_field_input_name(); ?>" value="<?php bp_the_profile_field_edit_value(); ?>" <?php if ( bp_get_the_profile_field_is_required() ) : ?>aria-required="true"<?php endif; ?>/> 713 <span class="description"><?php bp_the_profile_field_description(); ?></span> 714 </td> 698 while ( bp_profile_fields() ) : bp_the_profile_field(); ?> 715 699 716 <?php endif; ?> 717 718 <?php if ( 'textarea' === bp_get_the_profile_field_type() ) : ?> 700 <div<?php bp_field_css_class( 'bp-profile-field' ); ?>> 701 <?php 702 $field_type = bp_xprofile_create_field_type( bp_get_the_profile_field_type() ); 703 $field_type->edit_field_html( array( 'user_id' => $r['user_id'] ) ); 719 704 720 <th><label for="<?php bp_the_profile_field_input_name(); ?>"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php _e( '(required)', 'buddypress' ); ?><?php endif; ?></label></th> 721 <td class="admin-field-<?php bp_the_profile_field_type();?>"> 722 <textarea rows="5" cols="40" name="<?php bp_the_profile_field_input_name(); ?>" id="<?php bp_the_profile_field_input_name(); ?>" <?php if ( bp_get_the_profile_field_is_required() ) : ?>aria-required="true"<?php endif; ?>><?php bp_the_profile_field_edit_value(); ?></textarea> 723 <p class="description"><?php bp_the_profile_field_description(); ?></p> 724 </td> 725 726 <?php endif; ?> 705 if ( bp_get_the_profile_field_description() ) : ?> 706 <p class="description"><?php bp_the_profile_field_description(); ?></p> 707 <?php endif; 727 708 728 <?php if ( 'selectbox' === bp_get_the_profile_field_type() ) : ?> 709 do_action( 'bp_custom_profile_edit_fields_pre_visibility' ); 710 $can_change_visibility = bp_current_user_can( 'bp_xprofile_change_field_visibility' ); 711 ?> 729 712 730 <th><label for="<?php bp_the_profile_field_input_name(); ?>"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php _e( '(required)', 'buddypress' ); ?><?php endif; ?></label></th> 731 <td class="admin-field-<?php bp_the_profile_field_type();?>"> 732 <select name="<?php bp_the_profile_field_input_name(); ?>" id="<?php bp_the_profile_field_input_name(); ?>" <?php if ( bp_get_the_profile_field_is_required() ) : ?>aria-required="true"<?php endif; ?>> 733 <?php bp_the_profile_field_options( array( 'user_id' => $r['user_id'], ) ); ?> 734 </select> 735 <span class="description"><?php bp_the_profile_field_description(); ?></span> 736 </td> 713 <p class="field-visibility-settings-<?php echo $can_change_visibility ? 'toggle' : 'notoggle'; ?>" id="field-visibility-settings-toggle-<?php bp_the_profile_field_id(); ?>"> 714 <?php 715 printf( __( 'This field can be seen by: <span class="%s">%s</span>', 'buddypress' ), esc_attr( 'current-visibility-level' ), bp_get_the_profile_field_visibility_level_label() ); 737 716 717 if ( $can_change_visibility ) : ?> 718 <a href="#" class="button visibility-toggle-link"><?php _e( 'Change', 'buddypress' ); ?></a> 738 719 <?php endif; ?> 720 </p> 721 722 <?php if ( $can_change_visibility ) : ?> 723 <div class="field-visibility-settings" id="field-visibility-settings-<?php bp_the_profile_field_id() ?>"> 724 <fieldset> 725 <legend><?php _e( 'Who can see this field?', 'buddypress' ); ?></legend> 726 <?php bp_profile_visibility_radio_buttons(); ?> 727 </fieldset> 728 <a class="button field-visibility-settings-close" href="#"><?php _e( 'Close', 'buddypress' ); ?></a> 729 </div> 730 <?php endif; 739 731 740 <?php if ( 'multiselectbox' === bp_get_the_profile_field_type() ) : ?> 741 742 <th><label for="<?php bp_the_profile_field_input_name(); ?>"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php _e( '(required)', 'buddypress' ); ?><?php endif; ?></label></th> 743 <td class="admin-field-<?php bp_the_profile_field_type();?>"> 744 <select name="<?php bp_the_profile_field_input_name(); ?>" id="<?php bp_the_profile_field_input_name(); ?>" multiple="multiple" <?php if ( bp_get_the_profile_field_is_required() ) : ?>aria-required="true"<?php endif; ?>> 745 746 <?php bp_the_profile_field_options( array( 'user_id' => $r['user_id'], ) ); ?> 747 748 </select> 749 750 751 <?php if ( !bp_get_the_profile_field_is_required() ) : ?> 752 753 <p><a class="clear-value" href="javascript:clear( '<?php bp_the_profile_field_input_name(); ?>' );"><?php _e( 'Clear', 'buddypress' ); ?></a></p> 754 755 <?php endif; ?> 756 <p class="description"><?php bp_the_profile_field_description(); ?></p> 757 </td> 758 759 <?php endif; ?> 760 761 <?php if ( 'radio' === bp_get_the_profile_field_type() ) : ?> 762 763 <th> 764 <span class="label"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php _e( '(required)', 'buddypress' ); ?><?php endif; ?></span> 765 </th> 766 <td class="admin-field-<?php bp_the_profile_field_type();?>"> 767 <fieldset> 768 <legend class="screen-reader-text"><span><?php bp_the_profile_field_name(); ?></span></legend> 769 <?php bp_the_profile_field_options( array( 'user_id' => $r['user_id'], ) ); ?> 770 </fieldset> 771 772 <?php if ( !bp_get_the_profile_field_is_required() ) : ?> 773 774 <p><a class="clear-value" href="javascript:clear( '<?php bp_the_profile_field_input_name(); ?>' );"><?php _e( 'Clear', 'buddypress' ); ?></a></p> 775 776 <?php endif; ?> 777 <p class="description"><?php bp_the_profile_field_description(); ?></p> 778 </td> 779 780 <?php endif; ?> 781 782 <?php if ( 'checkbox' === bp_get_the_profile_field_type() ) : ?> 783 784 <th> 785 <span class="label"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php _e( '(required)', 'buddypress' ); ?><?php endif; ?></span> 786 </th> 787 <td class="admin-field-<?php bp_the_profile_field_type();?>"> 788 <?php bp_the_profile_field_options( array( 'user_id' => $r['user_id'], ) ); ?> 789 <p class="description"><?php bp_the_profile_field_description(); ?></p> 790 </td> 791 792 <?php endif; ?> 793 794 <?php if ( 'datebox' === bp_get_the_profile_field_type() ) : ?> 795 796 <th> 797 <label for="<?php bp_the_profile_field_input_name(); ?>_day"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php _e( '(required)', 'buddypress' ); ?><?php endif; ?></label> 798 </th> 799 <td class="admin-field-<?php bp_the_profile_field_type();?>"> 800 <select name="<?php bp_the_profile_field_input_name(); ?>_day" id="<?php bp_the_profile_field_input_name(); ?>_day" <?php if ( bp_get_the_profile_field_is_required() ) : ?>aria-required="true"<?php endif; ?>> 801 802 <?php bp_the_profile_field_options( array( 'user_id' => $r['user_id'], 'type' => 'day', ) ); ?> 803 804 </select> 805 806 <select name="<?php bp_the_profile_field_input_name(); ?>_month" id="<?php bp_the_profile_field_input_name(); ?>_month" <?php if ( bp_get_the_profile_field_is_required() ) : ?>aria-required="true"<?php endif; ?>> 807 808 <?php bp_the_profile_field_options( array( 'user_id' => $r['user_id'], 'type' => 'month', ) ); ?> 809 810 </select> 811 812 <select name="<?php bp_the_profile_field_input_name(); ?>_year" id="<?php bp_the_profile_field_input_name(); ?>_year" <?php if ( bp_get_the_profile_field_is_required() ) : ?>aria-required="true"<?php endif; ?>> 813 814 <?php bp_the_profile_field_options( array( 'user_id' => $r['user_id'], 'type' => 'year', ) ); ?> 815 816 </select> 817 <p class="description"><?php bp_the_profile_field_description(); ?></p> 818 </td> 819 820 <?php endif; ?> 821 822 </tr> 823 824 <tr class="admin-field-visibility-tr"> 825 <td class="admin-field-visibility-td"> </td> 826 <td class="admin-field-visibility-td"> 827 828 <?php do_action( 'bp_custom_profile_edit_fields_pre_visibility' ); ?> 829 830 <?php if ( bp_current_user_can( 'bp_xprofile_change_field_visibility' ) ) : ?> 831 <p class="description field-visibility-settings-toggle" id="field-visibility-settings-toggle-<?php bp_the_profile_field_id() ?>"> 832 <?php printf( __( 'This field can be seen by: <span class="current-visibility-level">%s</span>', 'buddypress' ), bp_get_the_profile_field_visibility_level_label() ) ?> <a href="#" class="visibility-toggle-link"><?php _e( 'Change', 'buddypress' ); ?></a> 833 </p> 834 835 <div class="field-visibility-settings" id="field-visibility-settings-<?php bp_the_profile_field_id() ?>"> 836 <fieldset> 837 <legend><?php esc_html_e( 'Who can see this field?', 'buddypress' ) ?></legend> 838 839 <?php bp_profile_visibility_radio_buttons() ?> 840 841 </fieldset> 842 <a class="field-visibility-settings-close" href="#"><?php esc_html_e( 'Close', 'buddypress' ) ?></a> 843 </div> 844 <?php else : ?> 845 <div class="field-visibility-settings-notoggle" id="field-visibility-settings-toggle-<?php bp_the_profile_field_id() ?>"> 846 <?php printf( __( 'This field can be seen by: <span class="current-visibility-level">%s</span>', 'buddypress' ), bp_get_the_profile_field_visibility_level_label() ) ?> 847 </div> 848 <?php endif ?> 849 850 </td> 851 </tr> 732 do_action( 'bp_custom_profile_edit_fields' ); ?> 733 </div> 852 734 853 <?php endwhile; ?>854 </tbody>735 <?php 736 endwhile; // bp_profile_fields() 855 737 856 </table> 857 <input type="hidden" name="field_ids[]" id="field_ids_<?php bp_the_profile_group_slug(); ?>" value="<?php bp_the_profile_group_field_ids(); ?>" /> 858 <?php endwhile; 738 endwhile; // bp_profile_groups() 859 739 endif; 860 740 } 861 741 -
bp-xprofile/bp-xprofile-classes.php
diff --git bp-xprofile/bp-xprofile-classes.php bp-xprofile/bp-xprofile-classes.php index 84fb54a..8699316 100644
class BP_XProfile_Field { 541 541 public $default_visibility = 'public'; 542 542 public $allow_custom_visibility = 'allowed'; 543 543 544 /** 545 * @since BuddyPress (2.0.0) 546 * @var BP_XProfile_Field_Type Field type object used for validation 547 */ 548 public $type_obj = null; 549 544 550 public $data; 545 551 public $message = null; 546 552 public $message_type = 'err'; 547 553 548 554 public function __construct( $id = null, $user_id = null, $get_data = true ) { 549 if ( !empty( $id ) ) 555 if ( !empty( $id ) ) { 550 556 $this->populate( $id, $user_id, $get_data ); 557 558 // Initialise the type obj to prevent fatals when creating new profile fields 559 } else { 560 $this->type_obj = bp_xprofile_create_field_type( 'textbox' ); 561 $this->type_obj->field_obj = $this; 562 } 551 563 } 552 564 553 565 public function populate( $id, $user_id, $get_data ) { … … class BP_XProfile_Field { 573 585 $this->order_by = $field->order_by; 574 586 $this->is_default_option = $field->is_default_option; 575 587 588 // Create the field type and store a reference back to this object. 589 $this->type_obj = bp_xprofile_create_field_type( $field->type ); 590 $this->type_obj->field_obj = $this; 591 576 592 if ( $get_data && $user_id ) { 577 593 $this->data = $this->get_field_data( $user_id ); 578 594 } … … class BP_XProfile_Field { 618 634 $this->order_by = apply_filters( 'xprofile_field_order_by_before_save', $this->order_by, $this->id ); 619 635 $this->field_order = apply_filters( 'xprofile_field_field_order_before_save', $this->field_order, $this->id ); 620 636 $this->can_delete = apply_filters( 'xprofile_field_can_delete_before_save', $this->can_delete, $this->id ); 637 $this->type_obj = bp_xprofile_create_field_type( $this->type ); 621 638 622 639 do_action_ref_array( 'xprofile_field_before_save', array( $this ) ); 623 640 … … class BP_XProfile_Field { 655 672 * Check to see if this is a field with child options. 656 673 * We need to add the options to the db, if it is. 657 674 */ 658 if ( 'radio' == $this->type || 'selectbox' == $this->type || 'checkbox' == $this->type || 'multiselectbox' == $this->type) {675 if ( $this->type_obj->supports_options ) { 659 676 660 677 if ( !empty( $this->id ) ) { 661 678 $parent_id = $this->id; … … class BP_XProfile_Field { 663 680 $parent_id = $wpdb->insert_id; 664 681 } 665 682 666 if ( 'radio' == $this->type ) { 667 $post_option = !empty( $_POST['radio_option'] ) ? $_POST['radio_option'] : ''; 668 $post_default = !empty( $_POST['isDefault_radio_option'] ) ? $_POST['isDefault_radio_option'] : ''; 669 670 $options = apply_filters( 'xprofile_field_options_before_save', $post_option, 'radio' ); 671 $defaults = apply_filters( 'xprofile_field_default_before_save', $post_default, 'radio' ); 672 673 } elseif ( 'selectbox' == $this->type ) { 674 $post_option = !empty( $_POST['selectbox_option'] ) ? $_POST['selectbox_option'] : ''; 675 $post_default = !empty( $_POST['isDefault_selectbox_option'] ) ? $_POST['isDefault_selectbox_option'] : ''; 676 677 $options = apply_filters( 'xprofile_field_options_before_save', $post_option, 'selectbox' ); 678 $defaults = apply_filters( 'xprofile_field_default_before_save', $post_default, 'selectbox' ); 679 680 } elseif ( 'multiselectbox' == $this->type ) { 681 $post_option = !empty( $_POST['multiselectbox_option'] ) ? $_POST['multiselectbox_option'] : ''; 682 $post_default = !empty( $_POST['isDefault_multiselectbox_option'] ) ? $_POST['isDefault_multiselectbox_option'] : ''; 683 684 $options = apply_filters( 'xprofile_field_options_before_save', $post_option, 'multiselectbox' ); 685 $defaults = apply_filters( 'xprofile_field_default_before_save', $post_default, 'multiselectbox' ); 686 687 } elseif ( 'checkbox' == $this->type ) { 688 $post_option = !empty( $_POST['checkbox_option'] ) ? $_POST['checkbox_option'] : ''; 689 $post_default = !empty( $_POST['isDefault_checkbox_option'] ) ? $_POST['isDefault_checkbox_option'] : ''; 690 691 $options = apply_filters( 'xprofile_field_options_before_save', $post_option, 'checkbox' ); 692 $defaults = apply_filters( 'xprofile_field_default_before_save', $post_default, 'checkbox' ); 693 } 683 // Allow plugins to filter the field's child options (i.e. the items in a selectbox). 684 $post_option = ! empty( $_POST["{$this->type}_option"] ) ? $_POST["{$this->type}_option"] : ''; 685 $post_default = ! empty( $_POST["isDefault_{$this->type}_option"] ) ? $_POST["isDefault_{$this->type}_option"] : ''; 686 $options = apply_filters( 'xprofile_field_options_before_save', $post_option, $this->type ); 687 $defaults = apply_filters( 'xprofile_field_default_before_save', $post_default, $this->type ); 694 688 695 689 $counter = 1; 696 690 if ( !empty( $options ) ) { … … class BP_XProfile_Field { 718 712 719 713 do_action_ref_array( 'xprofile_field_after_save', array( $this ) ); 720 714 715 // Recreate type_obj in case someone changed $this->type via a filter 716 $this->type_obj = bp_xprofile_create_field_type( $this->type ); 717 $this->type_obj->field_obj = $this; 718 721 719 return $field_id; 722 720 } else { 723 721 return false; … … class BP_XProfile_Field { 824 822 return false; 825 823 } 826 824 827 /* ADMIN AREA HTML. 828 * TODO: Get this out of here and replace with standard template loops 829 */ 830 831 /* This function populates the items for radio buttons checkboxes and drop down boxes */ 825 /** 826 * This function populates the items for radio buttons checkboxes and drop down boxes 827 */ 832 828 public function render_admin_form_children() { 833 $input_types = array( 'checkbox', 'selectbox', 'multiselectbox', 'radio' ); 834 835 foreach ( $input_types as $type ) { 836 $default_name = ''; 837 838 if ( ( 'multiselectbox' == $type ) || ( 'checkbox' == $type ) ) { 839 $default_input = 'checkbox'; 840 } else { 841 $default_input = 'radio'; 842 } 843 844 $class = $this->type != $type ? 'display: none;' : ''; 845 846 if ( empty( $this->default_visibility ) ) { 847 $this->default_visibility = 'public'; 848 } 849 850 ?> 851 852 <div id="<?php echo esc_attr( $type ); ?>" class="postbox bp-options-box" style="<?php echo esc_attr( $class ); ?> margin-top: 15px;"> 853 <h3><?php _e( 'Please enter options for this Field:', 'buddypress' ); ?></h3> 854 <div class="inside"> 855 <p> 856 <label for="sort_order_<?php echo esc_attr( $type ); ?>"><?php _e( 'Sort Order:', 'buddypress' ); ?></label> 857 <select name="sort_order_<?php echo esc_attr( $type ); ?>" id="sort_order_<?php echo esc_attr( $type ); ?>" > 858 <option value="custom" <?php selected( 'custom', $this->order_by ); ?>><?php _e( 'Custom', 'buddypress' ); ?></option> 859 <option value="asc" <?php selected( 'asc', $this->order_by ); ?>><?php _e( 'Ascending', 'buddypress' ); ?></option> 860 <option value="desc" <?php selected( 'desc', $this->order_by ); ?>><?php _e( 'Descending', 'buddypress' ); ?></option> 861 </select> 862 </p> 863 864 <?php if ( !$options = $this->get_children( true ) ) { 865 866 $i = 1; 867 while ( isset( $_POST[$type . '_option'][$i] ) ) { 868 (array) $options[] = (object) array( 869 'id' => -1, 870 'name' => $_POST[$type . '_option'][$i], 871 'is_default_option' => ( ( 'multiselectbox' != $type ) && ( 'checkbox' != $type ) && ( $_POST["isDefault_{$type}_option"] == $i ) ) ? 1 : $_POST["isDefault_{$type}_option"][$i] 872 ); 873 874 ++$i; 875 } 876 } 877 878 if ( !empty( $options ) ) { 879 for ( $i = 0, $count = count( $options ); $i < $count; ++$i ) { 880 $j = $i + 1; 881 882 if ( 'multiselectbox' == $type || 'checkbox' == $type ) 883 $default_name = '[' . $j . ']'; ?> 884 885 <p class="sortable"> 886 <span> Ξ </span> 887 <input type="text" name="<?php echo esc_attr( $type ); ?>_option[<?php echo esc_attr( $j ); ?>]" id="<?php echo esc_attr( $type ); ?>_option<?php echo esc_attr( $j ); ?>" value="<?php echo stripslashes( esc_attr( $options[$i]->name ) ); ?>" /> 888 <input type="<?php echo $default_input; ?>" name="isDefault_<?php echo esc_attr( $type ); ?>_option<?php echo esc_attr( $default_name ); ?>" <?php checked( (int) $options[$i]->is_default_option, true ); ?> value="<?php echo esc_attr( $j ); ?>" /> 889 <span><?php _e( 'Default Value', 'buddypress' ); ?></span> 890 <a href="<?php echo esc_url( 'users.php?page=bp-profile-setup&mode=delete_option&option_id=' . $options[$i]->id ); ?>" class="ajax-option-delete" id="delete-<?php echo esc_attr( $options[$i]->id ); ?>">[x]</a> 891 </p> 892 893 <?php } /* end for */ ?> 894 895 <input type="hidden" name="<?php echo esc_attr( $type ); ?>_option_number" id="<?php echo esc_attr( $type ); ?>_option_number" value="<?php echo esc_attr( (int) $j + 1 ); ?>" /> 896 897 <?php } else { 898 899 if ( 'multiselectbox' == $type || 'checkbox' == $type ) 900 $default_name = '[1]'; ?> 901 902 <p class="sortable"> 903 <span> Ξ </span> 904 <input type="text" name="<?php echo esc_attr( $type ); ?>_option[1]" id="<?php echo esc_attr( $type ); ?>_option1" /> 905 <input type="<?php echo esc_attr( $default_input ); ?>" name="isDefault_<?php echo esc_attr( $type ); ?>_option<?php echo esc_attr( $default_name ); ?>" id="isDefault_<?php echo esc_attr( $type ); ?>_option" value="1" /> 906 <span><?php _e( 'Default Value', 'buddypress' ); ?></span> 907 <input type="hidden" name="<?php echo esc_attr( $type ); ?>_option_number" id="<?php echo esc_attr( $type ); ?>_option_number" value="2" /> 908 </p> 909 910 <?php } /* end if */ ?> 911 912 <div id="<?php echo esc_attr( $type ); ?>_more"></div> 913 <p><a href="javascript:add_option('<?php echo esc_attr( $type ); ?>')"><?php _e( 'Add Another Option', 'buddypress' ); ?></a></p> 914 </div> 915 </div> 916 917 <?php } 829 foreach ( array_keys( bp_xprofile_get_field_types() ) as $field_type ) { 830 $type_obj = bp_xprofile_create_field_type( $field_type ); 831 $type_obj->admin_new_field_html( $this ); 832 } 918 833 } 919 834 920 835 public function render_admin_form( $message = '' ) { … … class BP_XProfile_Field { 1041 956 <h3><label for="fieldtype"><?php _e( 'Field Type', 'buddypress'); ?></label></h3> 1042 957 <div class="inside"> 1043 958 <select name="fieldtype" id="fieldtype" onchange="show_options(this.value)" style="width: 30%"> 1044 <optgroup label="<?php esc_attr_e( 'Single Fields', 'buddypress' ); ?>"> 1045 <option value="textbox" <?php selected( $this->type, 'textbox' ); ?>><?php _e( 'Text Box', 'buddypress' ); ?></option> 1046 <option value="textarea" <?php selected( $this->type, 'textarea' ); ?>><?php _e( 'Multi-line Text Area', 'buddypress' ); ?></option> 1047 <option value="datebox" <?php selected( $this->type, 'datebox' ); ?>><?php _e( 'Date Selector', 'buddypress' ); ?></option> 1048 </optgroup> 1049 <optgroup label="<?php esc_attr_e( 'Multi Fields', 'buddypress' ); ?>"> 1050 <option value="radio" <?php selected( $this->type, 'radio' ); ?>><?php _e( 'Radio Buttons', 'buddypress' ); ?></option> 1051 <option value="selectbox" <?php selected( $this->type, 'selectbox' ); ?>><?php _e( 'Drop Down Select Box', 'buddypress' ); ?></option> 1052 <option value="multiselectbox" <?php selected( $this->type, 'multiselectbox' ); ?>><?php _e( 'Multi Select Box', 'buddypress' ); ?></option> 1053 <option value="checkbox" <?php selected( $this->type, 'checkbox' ); ?>><?php _e( 'Checkboxes', 'buddypress' ); ?></option> 1054 </optgroup> 959 <?php bp_xprofile_admin_form_field_types( $this->type ); ?> 1055 960 </select> 1056 961 1057 <?php do_action_ref_array( 'xprofile_field_additional_options', array( $this ) ); ?>1058 1059 <?php $this->render_admin_form_children(); ?>962 <?php 963 // Deprecated filter, don't use. Go look at {@link BP_XProfile_Field_Type::admin_new_field_html()}. 964 do_action( 'xprofile_field_additional_options', $this ); 1060 965 966 $this->render_admin_form_children(); 967 ?> 1061 968 </div> 1062 969 </div> 1063 970 … … class BP_XProfile_Field { 1086 993 if ( '' == $_POST['title'] || '' == $_POST['required'] || '' == $_POST['fieldtype'] ) { 1087 994 $message = __( 'Please make sure you fill out all required fields.', 'buddypress' ); 1088 995 return false; 1089 } else if ( empty( $_POST['field_file'] ) && $_POST['fieldtype'] == 'radio' && empty( $_POST['radio_option'][1] ) ) { 1090 $message = __( 'Radio button field types require at least one option. Please add options below.', 'buddypress' ); 1091 return false; 1092 } else if ( empty( $_POST['field_file'] ) && $_POST['fieldtype'] == 'selectbox' && empty( $_POST['selectbox_option'][1] ) ) { 1093 $message = __( 'Select box field types require at least one option. Please add options below.', 'buddypress' ); 1094 return false; 1095 } else if ( empty( $_POST['field_file'] ) && $_POST['fieldtype'] == 'multiselectbox' && empty( $_POST['multiselectbox_option'][1] ) ) { 1096 $message = __( 'Select box field types require at least one option. Please add options below.', 'buddypress' ); 1097 return false; 1098 } else if ( empty( $_POST['field_file'] ) && $_POST['fieldtype'] == 'checkbox' && empty( $_POST['checkbox_option'][1] ) ) { 1099 $message = __( 'Checkbox field types require at least one option. Please add options below.', 'buddypress' ); 1100 return false; 1101 } else { 1102 return true; 996 997 } elseif ( empty( $_POST['field_file'] ) ) { 998 $field_type = bp_xprofile_create_field_type( $_POST['fieldtype'] ); 999 $option_name = "{$_POST['fieldtype']}_option"; 1000 1001 if ( $field_type->supports_options && isset( $_POST[$option_name] ) && empty( $_POST[$option_name][1] ) ) { 1002 $message = __( 'This field type require at least one option. Please add options below.', 'buddypress' ); 1003 return false; 1004 } 1103 1005 } 1006 1007 return true; 1104 1008 } 1105 1009 } 1106 1010 1107 1108 1011 class BP_XProfile_ProfileData { 1109 1012 public $id; 1110 1013 public $user_id; … … class BP_XProfile_ProfileData { 1540 1443 return $data[$field_name]; 1541 1444 } 1542 1445 } 1446 1447 /** 1448 * Datebox xprofile field type. 1449 * 1450 * @since BuddyPress (2.0.0) 1451 */ 1452 class BP_XProfile_Field_Type_Datebox extends BP_XProfile_Field_Type { 1453 1454 /** 1455 * Constructor for the datebox field type 1456 * 1457 * @since BuddyPress (2.0.0) 1458 */ 1459 public function __construct() { 1460 parent::__construct(); 1461 1462 $this->category = _x( 'Single Fields', 'xprofile field type category', 'buddypress' ); 1463 $this->name = _x( 'Date Selector', 'xprofile field type', 'buddypress' ); 1464 1465 $this->set_format( '/^\d{4}-\d{1,2}-\d{1,2} 00:00:00$/', 'replace' ); // "Y-m-d 00:00:00" 1466 do_action( 'bp_xprofile_field_type_datebox', $this ); 1467 } 1468 1469 /** 1470 * Output the edit field HTML for this field type. 1471 * 1472 * Must be used inside the {@link bp_profile_fields()} template loop. 1473 * 1474 * @param array $raw_properties Optional key/value array of {@link http://dev.w3.org/html5/markup/input.html permitted attributes} that you want to add. 1475 * @since BuddyPress (2.0.0) 1476 */ 1477 public function edit_field_html( array $raw_properties = array() ) { 1478 $user_id = bp_displayed_user_id(); 1479 1480 // user_id is a special optional parameter that we pass to {@link bp_the_profile_field_options()}. 1481 if ( isset( $raw_properties['user_id'] ) ) { 1482 $user_id = (int) $raw_properties['user_id']; 1483 unset( $raw_properties['user_id'] ); 1484 } 1485 1486 $day_html = $this->get_edit_field_html_elements( array_merge( 1487 array( 1488 'id' => bp_get_the_profile_field_input_name() . '_day', 1489 'name' => bp_get_the_profile_field_input_name() . '_day', 1490 ), 1491 $raw_properties 1492 ) ); 1493 1494 $month_html = $this->get_edit_field_html_elements( array_merge( 1495 array( 1496 'id' => bp_get_the_profile_field_input_name() . '_month', 1497 'name' => bp_get_the_profile_field_input_name() . '_month', 1498 ), 1499 $raw_properties 1500 ) ); 1501 1502 $year_html = $this->get_edit_field_html_elements( array_merge( 1503 array( 1504 'id' => bp_get_the_profile_field_input_name() . '_year', 1505 'name' => bp_get_the_profile_field_input_name() . '_year', 1506 ), 1507 $raw_properties 1508 ) ); 1509 ?> 1510 <div class="datebox"> 1511 1512 <label for="<?php bp_the_profile_field_input_name(); ?>_day"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php _e( '(required)', 'buddypress' ); ?><?php endif; ?></label> 1513 1514 <select <?php echo $day_html; ?>> 1515 <?php bp_the_profile_field_options( array( 'type' => 'day', 'user_id' => $user_id ) ); ?> 1516 </select> 1517 1518 <select <?php echo $month_html; ?>> 1519 <?php bp_the_profile_field_options( array( 'type' => 'month', 'user_id' => $user_id ) ); ?> 1520 </select> 1521 1522 <select <?php echo $year_html; ?>> 1523 <?php bp_the_profile_field_options( array( 'type' => 'year', 'user_id' => $user_id ) ); ?> 1524 </select> 1525 1526 </div> 1527 <?php 1528 } 1529 1530 /** 1531 * Output the edit field options HTML for this field type. 1532 * 1533 * BuddyPress considers a field's "options" to be, for example, the items in a selectbox. 1534 * These are stored seperately in the database, and their templating is handled seperately. 1535 * 1536 * This templating is seperate from {@link BP_XProfile_Field_Type::edit_field_html()} because 1537 * it's also used in the wp-admin screens when creating new fields, and for backwards compatibility. 1538 * 1539 * Must be used inside the {@link bp_profile_fields()} template loop. 1540 * 1541 * @param array $args Optional. The arguments passed to {@link bp_the_profile_field_options()}. 1542 * @since BuddyPress (2.0.0) 1543 */ 1544 public function edit_field_options_html( array $args = array() ) { 1545 $options = $this->field_obj->get_children(); 1546 $date = BP_XProfile_ProfileData::get_value_byid( $this->field_obj->id, $args['user_id'] ); 1547 1548 $day = 0; 1549 $month = 0; 1550 $year = 0; 1551 $html = ''; 1552 1553 // Set day, month, year defaults 1554 if ( ! empty( $date ) ) { 1555 1556 // If Unix timestamp 1557 if ( is_numeric( $date ) ) { 1558 $day = date( 'j', $date ); 1559 $month = date( 'F', $date ); 1560 $year = date( 'Y', $date ); 1561 1562 // If MySQL timestamp 1563 } else { 1564 $day = mysql2date( 'j', $date ); 1565 $month = mysql2date( 'F', $date, false ); // Not localized, so that selected() works below 1566 $year = mysql2date( 'Y', $date ); 1567 } 1568 } 1569 1570 // Check for updated posted values, and errors preventing them from being saved first time. 1571 if ( ! empty( $_POST['field_' . $this->field_obj->id . '_day'] ) ) { 1572 $new_day = (int) $_POST['field_' . $this->field_obj->id . '_day']; 1573 $day = ( $day != $new_day ) ? $new_day : $day; 1574 } 1575 1576 if ( ! empty( $_POST['field_' . $this->field_obj->id . '_month'] ) ) { 1577 $new_month = (int) $_POST['field_' . $this->field_obj->id . '_month']; 1578 $month = ( $month != $new_month ) ? $new_month : $month; 1579 } 1580 1581 if ( ! empty( $_POST['field_' . $this->field_obj->id . '_year'] ) ) { 1582 $new_year = date( 'j', (int) $_POST['field_' . $this->field_obj->id . '_year'] ); 1583 $year = ( $year != $new_year ) ? $new_year : $year; 1584 } 1585 1586 // $type will be passed by calling function when needed 1587 switch ( $args['type'] ) { 1588 case 'day': 1589 $html = sprintf( '<option value="" %1$s>%2$s</option>', selected( $day, 0, false ), /* translators: no option picked in select box */ __( '----', 'buddypress' ) ); 1590 1591 for ( $i = 1; $i < 32; ++$i ) { 1592 $html .= sprintf( '<option value="%1$s" %2$s>%3$s</option>', (int) $i, selected( $day, $i, false ), (int) $i ); 1593 } 1594 break; 1595 1596 case 'month': 1597 $eng_months = array( 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ); 1598 1599 $months = array( 1600 __( 'January', 'buddypress' ), 1601 __( 'February', 'buddypress' ), 1602 __( 'March', 'buddypress' ), 1603 __( 'April', 'buddypress' ), 1604 __( 'May', 'buddypress' ), 1605 __( 'June', 'buddypress' ), 1606 __( 'July', 'buddypress' ), 1607 __( 'August', 'buddypress' ), 1608 __( 'September', 'buddypress' ), 1609 __( 'October', 'buddypress' ), 1610 __( 'November', 'buddypress' ), 1611 __( 'December', 'buddypress' ) 1612 ); 1613 1614 $html = sprintf( '<option value="" %1$s>%2$s</option>', selected( $month, 0, false ), /* translators: no option picked in select box */ __( '----', 'buddypress' ) ); 1615 1616 for ( $i = 0; $i < 12; ++$i ) { 1617 $html .= sprintf( '<option value="%1$s" %2$s>%3$s</option>', esc_attr( $eng_months[$i] ), selected( $month, $eng_months[$i], false ), $months[$i] ); 1618 } 1619 break; 1620 1621 case 'year': 1622 $html = sprintf( '<option value="" %1$s>%2$s</option>', selected( $year, 0, false ), /* translators: no option picked in select box */ __( '----', 'buddypress' ) ); 1623 1624 for ( $i = 2037; $i > 1901; $i-- ) { 1625 $html .= sprintf( '<option value="%1$s" %2$s>%3$s</option>', (int) $i, selected( $year, $i, false ), (int) $i ); 1626 } 1627 break; 1628 } 1629 1630 echo apply_filters( 'bp_get_the_profile_field_datebox', $html, $args['type'], $day, $month, $year, $this->field_obj->id, $date ); 1631 } 1632 1633 /** 1634 * Output HTML for this field type on the wp-admin Profile Fields screen. 1635 * 1636 * Must be used inside the {@link bp_profile_fields()} template loop. 1637 * 1638 * @param array $raw_properties Optional key/value array of permitted attributes that you want to add. 1639 * @since BuddyPress (2.0.0) 1640 */ 1641 public function admin_field_html( array $raw_properties = array() ) { 1642 $day_html = $this->get_edit_field_html_elements( array_merge( 1643 array( 1644 'id' => bp_get_the_profile_field_input_name() . '_day', 1645 'name' => bp_get_the_profile_field_input_name() . '_day', 1646 ), 1647 $raw_properties 1648 ) ); 1649 1650 $month_html = $this->get_edit_field_html_elements( array_merge( 1651 array( 1652 'id' => bp_get_the_profile_field_input_name() . '_month', 1653 'name' => bp_get_the_profile_field_input_name() . '_month', 1654 ), 1655 $raw_properties 1656 ) ); 1657 1658 $year_html = $this->get_edit_field_html_elements( array_merge( 1659 array( 1660 'id' => bp_get_the_profile_field_input_name() . '_year', 1661 'name' => bp_get_the_profile_field_input_name() . '_year', 1662 ), 1663 $raw_properties 1664 ) ); 1665 ?> 1666 <select <?php echo $day_html; ?>> 1667 <?php bp_the_profile_field_options( 'type=day' ); ?> 1668 </select> 1669 1670 <select <?php echo $month_html; ?>> 1671 <?php bp_the_profile_field_options( 'type=month' ); ?> 1672 </select> 1673 1674 <select <?php echo $year_html; ?>> 1675 <?php bp_the_profile_field_options( 'type=year' ); ?> 1676 </select> 1677 <?php 1678 } 1679 1680 /** 1681 * This method usually outputs HTML for this field type's children options on the wp-admin Profile Fields 1682 * "Add Field" and "Edit Field" screens, but for this field type, we don't want it, so it's stubbed out. 1683 * 1684 * @param BP_XProfile_Field $current_field The current profile field on the add/edit screen. 1685 * @param string $control_type Optional. HTML input type used to render the current field's child options. 1686 * @since BuddyPress (2.0.0) 1687 */ 1688 public function admin_new_field_html( BP_XProfile_Field $current_field, $control_type = '' ) {} 1689 } 1690 1691 /** 1692 * Checkbox xprofile field type. 1693 * 1694 * @since BuddyPress (2.0.0) 1695 */ 1696 class BP_XProfile_Field_Type_Checkbox extends BP_XProfile_Field_Type { 1697 1698 /** 1699 * Constructor for the checkbox field type 1700 * 1701 * @since BuddyPress (2.0.0) 1702 */ 1703 public function __construct() { 1704 parent::__construct(); 1705 1706 $this->category = _x( 'Multi Fields', 'xprofile field type category', 'buddypress' ); 1707 $this->name = _x( 'Checkboxes', 'xprofile field type', 'buddypress' ); 1708 1709 $this->supports_multiple_defaults = true; 1710 $this->accepts_null_value = true; 1711 $this->supports_options = true; 1712 1713 $this->set_format( '/^.+$/', 'replace' ); 1714 do_action( 'bp_xprofile_field_type_checkbox', $this ); 1715 } 1716 1717 /** 1718 * Output the edit field HTML for this field type. 1719 * 1720 * Must be used inside the {@link bp_profile_fields()} template loop. 1721 * 1722 * @param array $raw_properties Optional key/value array of {@link http://dev.w3.org/html5/markup/input.checkbox.html permitted attributes} that you want to add. 1723 * @since BuddyPress (2.0.0) 1724 */ 1725 public function edit_field_html( array $raw_properties = array() ) { 1726 $user_id = bp_displayed_user_id(); 1727 1728 // user_id is a special optional parameter that we pass to {@link bp_the_profile_field_options()}. 1729 if ( isset( $raw_properties['user_id'] ) ) { 1730 $user_id = (int) $raw_properties['user_id']; 1731 unset( $raw_properties['user_id'] ); 1732 } 1733 ?> 1734 <div class="checkbox"> 1735 1736 <label for="<?php bp_the_profile_field_input_name(); ?>"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php _e( '(required)', 'buddypress' ); ?><?php endif; ?></label> 1737 <?php bp_the_profile_field_options( "user_id={$user_id}" ); ?> 1738 1739 </div> 1740 <?php 1741 } 1742 1743 /** 1744 * Output the edit field options HTML for this field type. 1745 * 1746 * BuddyPress considers a field's "options" to be, for example, the items in a selectbox. 1747 * These are stored seperately in the database, and their templating is handled seperately. 1748 * 1749 * This templating is seperate from {@link BP_XProfile_Field_Type::edit_field_html()} because 1750 * it's also used in the wp-admin screens when creating new fields, and for backwards compatibility. 1751 * 1752 * Must be used inside the {@link bp_profile_fields()} template loop. 1753 * 1754 * @param array $args Optional. The arguments passed to {@link bp_the_profile_field_options()}. 1755 * @since BuddyPress (2.0.0) 1756 */ 1757 public function edit_field_options_html( array $args = array() ) { 1758 $options = $this->field_obj->get_children(); 1759 $option_values = BP_XProfile_ProfileData::get_value_byid( $this->field_obj->id, $args['user_id'] ); 1760 $option_values = (array) maybe_unserialize( $option_values ); 1761 1762 $html = ''; 1763 1764 // Check for updated posted values, but errors preventing them from being saved first time 1765 if ( isset( $_POST['field_' . $this->field_obj->id] ) && $option_values != maybe_serialize( $_POST['field_' . $this->field_obj->id] ) ) { 1766 if ( ! empty( $_POST['field_' . $this->field_obj->id] ) ) { 1767 $option_values = array_map( 'sanitize_text_field', $_POST['field_' . $this->field_obj->id] ); 1768 } 1769 } 1770 1771 for ( $k = 0, $count = count( $options ); $k < $count; ++$k ) { 1772 $selected = ''; 1773 1774 // First, check to see whether the user's saved values match the option 1775 for ( $j = 0, $count_values = count( $option_values ); $j < $count_values; ++$j ) { 1776 1777 // Run the allowed option name through the before_save filter, so we'll be sure to get a match 1778 $allowed_options = xprofile_sanitize_data_value_before_save( $options[$k]->name, false, false ); 1779 1780 if ( $option_values[$j] === $allowed_options || in_array( $allowed_options, $option_values ) ) { 1781 $selected = ' checked="checked"'; 1782 break; 1783 } 1784 } 1785 1786 // If the user has not yet supplied a value for this field, check to see whether there is a default value available 1787 if ( ! is_array( $option_values ) && empty( $option_values ) && empty( $selected ) && ! empty( $options[$k]->is_default_option ) ) { 1788 $selected = ' checked="checked"'; 1789 } 1790 1791 $new_html = sprintf( '<label><input %1$s type="checkbox" name="%2$s" id="%3$s" value="%4$s">%5$s</label>', 1792 $selected, 1793 esc_attr( "field_{$this->field_obj->id}[]" ), 1794 esc_attr( "field_{$options[$k]->id}_{$k}" ), 1795 esc_attr( stripslashes( $options[$k]->name ) ), 1796 esc_html( stripslashes( $options[$k]->name ) ) 1797 ); 1798 $html .= apply_filters( 'bp_get_the_profile_field_options_checkbox', $new_html, $options[$k], $this->field_obj->id, $selected, $k ); 1799 } 1800 1801 echo $html; 1802 } 1803 1804 /** 1805 * Output HTML for this field type on the wp-admin Profile Fields screen. 1806 * 1807 * Must be used inside the {@link bp_profile_fields()} template loop. 1808 * 1809 * @param array $raw_properties Optional key/value array of permitted attributes that you want to add. 1810 * @since BuddyPress (2.0.0) 1811 */ 1812 public function admin_field_html( array $raw_properties = array() ) { 1813 bp_the_profile_field_options(); 1814 } 1815 1816 /** 1817 * Output HTML for this field type's children options on the wp-admin Profile Fields "Add Field" and "Edit Field" screens. 1818 * 1819 * Must be used inside the {@link bp_profile_fields()} template loop. 1820 * 1821 * @param BP_XProfile_Field $current_field The current profile field on the add/edit screen. 1822 * @param string $control_type Optional. HTML input type used to render the current field's child options. 1823 * @since BuddyPress (2.0.0) 1824 */ 1825 public function admin_new_field_html( BP_XProfile_Field $current_field, $control_type = '' ) { 1826 parent::admin_new_field_html( $current_field, 'checkbox' ); 1827 } 1828 } 1829 1830 /** 1831 * Radio button xprofile field type. 1832 * 1833 * @since BuddyPress (2.0.0) 1834 */ 1835 class BP_XProfile_Field_Type_Radiobutton extends BP_XProfile_Field_Type { 1836 1837 /** 1838 * Constructor for the radio button field type 1839 * 1840 * @since BuddyPress (2.0.0) 1841 */ 1842 public function __construct() { 1843 parent::__construct(); 1844 1845 $this->category = _x( 'Multi Fields', 'xprofile field type category', 'buddypress' ); 1846 $this->name = _x( 'Radio Buttons', 'xprofile field type', 'buddypress' ); 1847 1848 $this->supports_options = true; 1849 1850 $this->set_format( '/^.+$/', 'replace' ); 1851 do_action( 'bp_xprofile_field_type_radiobutton', $this ); 1852 } 1853 1854 /** 1855 * Output the edit field HTML for this field type. 1856 * 1857 * Must be used inside the {@link bp_profile_fields()} template loop. 1858 * 1859 * @param array $raw_properties Optional key/value array of {@link http://dev.w3.org/html5/markup/input.radio.html permitted attributes} that you want to add. 1860 * @since BuddyPress (2.0.0) 1861 */ 1862 public function edit_field_html( array $raw_properties = array() ) { 1863 $user_id = bp_displayed_user_id(); 1864 1865 // user_id is a special optional parameter that we pass to {@link bp_the_profile_field_options()}. 1866 if ( isset( $raw_properties['user_id'] ) ) { 1867 $user_id = (int) $raw_properties['user_id']; 1868 unset( $raw_properties['user_id'] ); 1869 } 1870 ?> 1871 <div class="radio"> 1872 1873 <label for="<?php bp_the_profile_field_input_name(); ?>"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php _e( '(required)', 'buddypress' ); ?><?php endif; ?></label> 1874 <?php bp_the_profile_field_options( "user_id={$user_id}" ); 1875 1876 if ( ! bp_get_the_profile_field_is_required() ) : ?> 1877 <a class="clear-value" href="javascript:clear( '<?php echo esc_js( bp_get_the_profile_field_input_name() ); ?>' );"><?php _e( 'Clear', 'buddypress' ); ?></a> 1878 <?php endif; ?> 1879 1880 </div> 1881 <?php 1882 } 1883 1884 /** 1885 * Output the edit field options HTML for this field type. 1886 * 1887 * BuddyPress considers a field's "options" to be, for example, the items in a selectbox. 1888 * These are stored seperately in the database, and their templating is handled seperately. 1889 * 1890 * This templating is seperate from {@link BP_XProfile_Field_Type::edit_field_html()} because 1891 * it's also used in the wp-admin screens when creating new fields, and for backwards compatibility. 1892 * 1893 * Must be used inside the {@link bp_profile_fields()} template loop. 1894 * 1895 * @param array $args Optional. The arguments passed to {@link bp_the_profile_field_options()}. 1896 * @since BuddyPress (2.0.0) 1897 */ 1898 public function edit_field_options_html( array $args = array() ) { 1899 $option_value = BP_XProfile_ProfileData::get_value_byid( $this->field_obj->id, $args['user_id'] ); 1900 $options = $this->field_obj->get_children(); 1901 1902 $html = sprintf( '<div id="%s">', esc_attr( 'field_' . $this->field_obj->id ) ); 1903 1904 for ( $k = 0, $count = count( $options ); $k < $count; ++$k ) { 1905 1906 // Check for updated posted values, but errors preventing them from being saved first time 1907 if ( isset( $_POST['field_' . $this->field_obj->id] ) && $option_value != $_POST['field_' . $this->field_obj->id] ) { 1908 if ( ! empty( $_POST['field_' . $this->field_obj->id] ) ) { 1909 $option_value = sanitize_text_field( $_POST['field_' . $this->field_obj->id] ); 1910 } 1911 } 1912 1913 // Run the allowed option name through the before_save filter, so we'll be sure to get a match 1914 $allowed_options = xprofile_sanitize_data_value_before_save( $options[$k]->name, false, false ); 1915 $selected = ''; 1916 1917 if ( $option_value === $allowed_options || ( empty( $option_value ) && ! empty( $options[$k]->is_default_option ) ) ) { 1918 $selected = ' checked="checked"'; 1919 } 1920 1921 $new_html = sprintf( '<label><input %1$s type="radio" name="%2$s" id="%3$s" value="%4$s">%5$s</label>', 1922 $selected, 1923 esc_attr( "field_{$this->field_obj->id}" ), 1924 esc_attr( "option_{$options[$k]->id}" ), 1925 esc_attr( stripslashes( $options[$k]->name ) ), 1926 esc_html( stripslashes( $options[$k]->name ) ) 1927 ); 1928 $html .= apply_filters( 'bp_get_the_profile_field_options_radio', $new_html, $options[$k], $this->field_obj->id, $selected, $k ); 1929 } 1930 1931 echo $html . '</div>'; 1932 } 1933 1934 /** 1935 * Output HTML for this field type on the wp-admin Profile Fields screen. 1936 * 1937 * Must be used inside the {@link bp_profile_fields()} template loop. 1938 * 1939 * @param array $raw_properties Optional key/value array of permitted attributes that you want to add. 1940 * @since BuddyPress (2.0.0) 1941 */ 1942 public function admin_field_html( array $raw_properties = array() ) { 1943 bp_the_profile_field_options(); 1944 1945 if ( ! bp_get_the_profile_field_is_required() ) : ?> 1946 <a class="clear-value" href="javascript:clear( '<?php echo esc_js( bp_get_the_profile_field_input_name() ); ?>' );"><?php _e( 'Clear', 'buddypress' ); ?></a> 1947 <?php endif; ?> 1948 <?php 1949 } 1950 1951 /** 1952 * Output HTML for this field type's children options on the wp-admin Profile Fields "Add Field" and "Edit Field" screens. 1953 * 1954 * Must be used inside the {@link bp_profile_fields()} template loop. 1955 * 1956 * @param BP_XProfile_Field $current_field The current profile field on the add/edit screen. 1957 * @param string $control_type Optional. HTML input type used to render the current field's child options. 1958 * @since BuddyPress (2.0.0) 1959 */ 1960 public function admin_new_field_html( BP_XProfile_Field $current_field, $control_type = '' ) { 1961 parent::admin_new_field_html( $current_field, 'radio' ); 1962 } 1963 } 1964 1965 /** 1966 * Multi-selectbox xprofile field type. 1967 * 1968 * @since BuddyPress (2.0.0) 1969 */ 1970 class BP_XProfile_Field_Type_Multiselectbox extends BP_XProfile_Field_Type { 1971 1972 /** 1973 * Constructor for the multi-selectbox field type 1974 * 1975 * @since BuddyPress (2.0.0) 1976 */ 1977 public function __construct() { 1978 parent::__construct(); 1979 1980 $this->category = _x( 'Multi Fields', 'xprofile field type category', 'buddypress' ); 1981 $this->name = _x( 'Multi Select Box', 'xprofile field type', 'buddypress' ); 1982 1983 $this->supports_multiple_defaults = true; 1984 $this->accepts_null_value = true; 1985 $this->supports_options = true; 1986 1987 $this->set_format( '/^.+$/', 'replace' ); 1988 do_action( 'bp_xprofile_field_type_multiselectbox', $this ); 1989 } 1990 1991 /** 1992 * Output the edit field HTML for this field type. 1993 * 1994 * Must be used inside the {@link bp_profile_fields()} template loop. 1995 * 1996 * @param array $raw_properties Optional key/value array of {@link http://dev.w3.org/html5/markup/select.html permitted attributes} that you want to add. 1997 * @since BuddyPress (2.0.0) 1998 */ 1999 public function edit_field_html( array $raw_properties = array() ) { 2000 $user_id = bp_displayed_user_id(); 2001 2002 // user_id is a special optional parameter that we pass to {@link bp_the_profile_field_options()}. 2003 if ( isset( $raw_properties['user_id'] ) ) { 2004 $user_id = (int) $raw_properties['user_id']; 2005 unset( $raw_properties['user_id'] ); 2006 } 2007 2008 $html = $this->get_edit_field_html_elements( array_merge( 2009 array( 'multiple' => 'multiple' ), 2010 $raw_properties 2011 ) ); 2012 ?> 2013 <label for="<?php bp_the_profile_field_input_name(); ?>[]"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php _e( '(required)', 'buddypress' ); ?><?php endif; ?></label> 2014 <select <?php echo $html; ?>> 2015 <?php bp_the_profile_field_options( "user_id={$user_id}" ); ?> 2016 </select> 2017 2018 <?php if ( ! bp_get_the_profile_field_is_required() ) : ?> 2019 <a class="clear-value" href="javascript:clear( '<?php echo esc_js( bp_get_the_profile_field_input_name() ); ?>[]' );"><?php _e( 'Clear', 'buddypress' ); ?></a> 2020 <?php endif; ?> 2021 <?php 2022 } 2023 2024 /** 2025 * Output the edit field options HTML for this field type. 2026 * 2027 * BuddyPress considers a field's "options" to be, for example, the items in a selectbox. 2028 * These are stored seperately in the database, and their templating is handled seperately. 2029 * 2030 * This templating is seperate from {@link BP_XProfile_Field_Type::edit_field_html()} because 2031 * it's also used in the wp-admin screens when creating new fields, and for backwards compatibility. 2032 * 2033 * Must be used inside the {@link bp_profile_fields()} template loop. 2034 * 2035 * @param array $args Optional. The arguments passed to {@link bp_the_profile_field_options()}. 2036 * @since BuddyPress (2.0.0) 2037 */ 2038 public function edit_field_options_html( array $args = array() ) { 2039 $original_option_values = maybe_unserialize( BP_XProfile_ProfileData::get_value_byid( $this->field_obj->id, $args['user_id'] ) ); 2040 2041 $options = $this->field_obj->get_children(); 2042 $html = ''; 2043 2044 if ( empty( $original_option_values ) && ! empty( $_POST['field_' . $this->field_obj->id] ) ) { 2045 $original_option_values = sanitize_text_field( $_POST['field_' . $this->field_obj->id] ); 2046 } 2047 2048 $option_values = (array) $original_option_values; 2049 for ( $k = 0, $count = count( $options ); $k < $count; ++$k ) { 2050 $selected = ''; 2051 2052 // Check for updated posted values, but errors preventing them from being saved first time 2053 foreach( $option_values as $i => $option_value ) { 2054 if ( isset( $_POST['field_' . $this->field_obj->id] ) && $_POST['field_' . $this->field_obj->id][$i] != $option_value ) { 2055 if ( ! empty( $_POST['field_' . $this->field_obj->id][$i] ) ) { 2056 $option_values[] = sanitize_text_field( $_POST['field_' . $this->field_obj->id][$i] ); 2057 } 2058 } 2059 } 2060 2061 // Run the allowed option name through the before_save filter, so we'll be sure to get a match 2062 $allowed_options = xprofile_sanitize_data_value_before_save( $options[$k]->name, false, false ); 2063 2064 // First, check to see whether the user-entered value matches 2065 if ( in_array( $allowed_options, $option_values ) ) { 2066 $selected = ' selected="selected"'; 2067 } 2068 2069 // Then, if the user has not provided a value, check for defaults 2070 if ( ! is_array( $original_option_values ) && empty( $option_values ) && ! empty( $options[$k]->is_default_option ) ) { 2071 $selected = ' selected="selected"'; 2072 } 2073 2074 $html .= apply_filters( 'bp_get_the_profile_field_options_multiselect', '<option' . $selected . ' value="' . esc_attr( stripslashes( $options[$k]->name ) ) . '">' . esc_html( stripslashes( $options[$k]->name ) ) . '</option>', $options[$k], $this->field_obj->id, $selected, $k ); 2075 } 2076 2077 echo $html; 2078 } 2079 2080 /** 2081 * Output HTML for this field type on the wp-admin Profile Fields screen. 2082 * 2083 * Must be used inside the {@link bp_profile_fields()} template loop. 2084 * 2085 * @param array $raw_properties Optional key/value array of permitted attributes that you want to add. 2086 * @since BuddyPress (2.0.0) 2087 */ 2088 public function admin_field_html( array $raw_properties = array() ) { 2089 $html = $this->get_edit_field_html_elements( array_merge( 2090 array( 'multiple' => 'multiple' ), 2091 $raw_properties 2092 ) ); 2093 ?> 2094 <select <?php echo $html; ?>> 2095 <?php bp_the_profile_field_options(); ?> 2096 </select> 2097 <?php 2098 } 2099 2100 /** 2101 * Output HTML for this field type's children options on the wp-admin Profile Fields "Add Field" and "Edit Field" screens. 2102 * 2103 * Must be used inside the {@link bp_profile_fields()} template loop. 2104 * 2105 * @param BP_XProfile_Field $current_field The current profile field on the add/edit screen. 2106 * @param string $control_type Optional. HTML input type used to render the current field's child options. 2107 * @since BuddyPress (2.0.0) 2108 */ 2109 public function admin_new_field_html( BP_XProfile_Field $current_field, $control_type = '' ) { 2110 parent::admin_new_field_html( $current_field, 'checkbox' ); 2111 } 2112 } 2113 2114 /** 2115 * Selectbox xprofile field type. 2116 * 2117 * @since BuddyPress (2.0.0) 2118 */ 2119 class BP_XProfile_Field_Type_Selectbox extends BP_XProfile_Field_Type { 2120 2121 /** 2122 * Constructor for the selectbox field type 2123 * 2124 * @since BuddyPress (2.0.0) 2125 */ 2126 public function __construct() { 2127 parent::__construct(); 2128 2129 $this->category = _x( 'Multi Fields', 'xprofile field type category', 'buddypress' ); 2130 $this->name = _x( 'Drop Down Select Box', 'xprofile field type', 'buddypress' ); 2131 2132 $this->supports_options = true; 2133 2134 $this->set_format( '/^.+$/', 'replace' ); 2135 do_action( 'bp_xprofile_field_type_selectbox', $this ); 2136 } 2137 2138 /** 2139 * Output the edit field HTML for this field type. 2140 * 2141 * Must be used inside the {@link bp_profile_fields()} template loop. 2142 * 2143 * @param array $raw_properties Optional key/value array of {@link http://dev.w3.org/html5/markup/select.html permitted attributes} that you want to add. 2144 * @since BuddyPress (2.0.0) 2145 */ 2146 public function edit_field_html( array $raw_properties = array() ) { 2147 $user_id = bp_displayed_user_id(); 2148 2149 // user_id is a special optional parameter that we pass to {@link bp_the_profile_field_options()}. 2150 if ( isset( $raw_properties['user_id'] ) ) { 2151 $user_id = (int) $raw_properties['user_id']; 2152 unset( $raw_properties['user_id'] ); 2153 } 2154 2155 $html = $this->get_edit_field_html_elements( $raw_properties ); 2156 ?> 2157 <label for="<?php bp_the_profile_field_input_name(); ?>"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php _e( '(required)', 'buddypress' ); ?><?php endif; ?></label> 2158 <select <?php echo $html; ?>> 2159 <?php bp_the_profile_field_options( "user_id={$user_id}" ); ?> 2160 </select> 2161 <?php 2162 } 2163 2164 /** 2165 * Output the edit field options HTML for this field type. 2166 * 2167 * BuddyPress considers a field's "options" to be, for example, the items in a selectbox. 2168 * These are stored seperately in the database, and their templating is handled seperately. 2169 * 2170 * This templating is seperate from {@link BP_XProfile_Field_Type::edit_field_html()} because 2171 * it's also used in the wp-admin screens when creating new fields, and for backwards compatibility. 2172 * 2173 * Must be used inside the {@link bp_profile_fields()} template loop. 2174 * 2175 * @param array $args Optional. The arguments passed to {@link bp_the_profile_field_options()}. 2176 * @since BuddyPress (2.0.0) 2177 */ 2178 public function edit_field_options_html( array $args = array() ) { 2179 $original_option_values = maybe_unserialize( BP_XProfile_ProfileData::get_value_byid( $this->field_obj->id, $args['user_id'] ) ); 2180 2181 $options = $this->field_obj->get_children(); 2182 $html = '<option value="">' . /* translators: no option picked in select box */ __( '----', 'buddypress' ) . '</option>'; 2183 2184 if ( empty( $original_option_values ) && !empty( $_POST['field_' . $this->field_obj->id] ) ) { 2185 $original_option_values = sanitize_text_field( $_POST['field_' . $this->field_obj->id] ); 2186 } 2187 2188 $option_values = (array) $original_option_values; 2189 for ( $k = 0, $count = count( $options ); $k < $count; ++$k ) { 2190 $selected = ''; 2191 2192 // Check for updated posted values, but errors preventing them from being saved first time 2193 foreach( $option_values as $i => $option_value ) { 2194 if ( isset( $_POST['field_' . $this->field_obj->id] ) && $_POST['field_' . $this->field_obj->id] != $option_value ) { 2195 if ( ! empty( $_POST['field_' . $this->field_obj->id] ) ) { 2196 $option_values[$i] = sanitize_text_field( $_POST['field_' . $this->field_obj->id] ); 2197 } 2198 } 2199 } 2200 2201 // Run the allowed option name through the before_save filter, so we'll be sure to get a match 2202 $allowed_options = xprofile_sanitize_data_value_before_save( $options[$k]->name, false, false ); 2203 2204 // First, check to see whether the user-entered value matches 2205 if ( in_array( $allowed_options, $option_values ) ) { 2206 $selected = ' selected="selected"'; 2207 } 2208 2209 // Then, if the user has not provided a value, check for defaults 2210 if ( ! is_array( $original_option_values ) && empty( $option_values ) && $options[$k]->is_default_option ) { 2211 $selected = ' selected="selected"'; 2212 } 2213 2214 $html .= apply_filters( 'bp_get_the_profile_field_options_select', '<option' . $selected . ' value="' . esc_attr( stripslashes( $options[$k]->name ) ) . '">' . esc_html( stripslashes( $options[$k]->name ) ) . '</option>', $options[$k], $this->field_obj->id, $selected, $k ); 2215 } 2216 2217 echo $html; 2218 } 2219 2220 /** 2221 * Output HTML for this field type on the wp-admin Profile Fields screen. 2222 * 2223 * Must be used inside the {@link bp_profile_fields()} template loop. 2224 * 2225 * @param array $raw_properties Optional key/value array of permitted attributes that you want to add. 2226 * @since BuddyPress (2.0.0) 2227 */ 2228 public function admin_field_html( array $raw_properties = array() ) { 2229 $html = $this->get_edit_field_html_elements( $raw_properties ); 2230 ?> 2231 <select <?php echo $html; ?>> 2232 <?php bp_the_profile_field_options(); ?> 2233 </select> 2234 <?php 2235 } 2236 2237 /** 2238 * Output HTML for this field type's children options on the wp-admin Profile Fields "Add Field" and "Edit Field" screens. 2239 * 2240 * Must be used inside the {@link bp_profile_fields()} template loop. 2241 * 2242 * @param BP_XProfile_Field $current_field The current profile field on the add/edit screen. 2243 * @param string $control_type Optional. HTML input type used to render the current field's child options. 2244 * @since BuddyPress (2.0.0) 2245 */ 2246 public function admin_new_field_html( BP_XProfile_Field $current_field, $control_type = '' ) { 2247 parent::admin_new_field_html( $current_field, 'radio' ); 2248 } 2249 } 2250 2251 /** 2252 * Textarea xprofile field type. 2253 * 2254 * @since BuddyPress (2.0.0) 2255 */ 2256 class BP_XProfile_Field_Type_Textarea extends BP_XProfile_Field_Type { 2257 2258 /** 2259 * Constructor for the textarea field type 2260 * 2261 * @since BuddyPress (2.0.0) 2262 */ 2263 public function __construct() { 2264 parent::__construct(); 2265 2266 $this->category = _x( 'Single Fields', 'xprofile field type category', 'buddypress' ); 2267 $this->name = _x( 'Multi-line Text Area', 'xprofile field type', 'buddypress' ); 2268 2269 $this->set_format( '/^.*$/m', 'replace' ); 2270 do_action( 'bp_xprofile_field_type_textarea', $this ); 2271 } 2272 2273 /** 2274 * Output the edit field HTML for this field type. 2275 * 2276 * Must be used inside the {@link bp_profile_fields()} template loop. 2277 * 2278 * @param array $raw_properties Optional key/value array of {@link http://dev.w3.org/html5/markup/textarea.html permitted attributes} that you want to add. 2279 * @since BuddyPress (2.0.0) 2280 */ 2281 public function edit_field_html( array $raw_properties = array() ) { 2282 2283 // user_id is a special optional parameter that certain other fields types pass to {@link bp_the_profile_field_options()}. 2284 if ( isset( $raw_properties['user_id'] ) ) { 2285 unset( $raw_properties['user_id'] ); 2286 } 2287 2288 $html = $this->get_edit_field_html_elements( array_merge( 2289 array( 2290 'cols' => 40, 2291 'rows' => 5, 2292 ), 2293 $raw_properties 2294 ) ); 2295 ?> 2296 <label for="<?php bp_the_profile_field_input_name(); ?>"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php _e( '(required)', 'buddypress' ); ?><?php endif; ?></label> 2297 <textarea <?php echo $html; ?>><?php bp_the_profile_field_edit_value(); ?></textarea> 2298 <?php 2299 } 2300 2301 /** 2302 * Output HTML for this field type on the wp-admin Profile Fields screen. 2303 * 2304 * Must be used inside the {@link bp_profile_fields()} template loop. 2305 * 2306 * @param array $raw_properties Optional key/value array of permitted attributes that you want to add. 2307 * @since BuddyPress (2.0.0) 2308 */ 2309 public function admin_field_html( array $raw_properties = array() ) { 2310 $html = $this->get_edit_field_html_elements( array_merge( 2311 array( 2312 'cols' => 40, 2313 'rows' => 5, 2314 ), 2315 $raw_properties 2316 ) ); 2317 ?> 2318 <textarea <?php echo $html; ?>></textarea> 2319 <?php 2320 } 2321 2322 /** 2323 * This method usually outputs HTML for this field type's children options on the wp-admin Profile Fields 2324 * "Add Field" and "Edit Field" screens, but for this field type, we don't want it, so it's stubbed out. 2325 * 2326 * @param BP_XProfile_Field $current_field The current profile field on the add/edit screen. 2327 * @param string $control_type Optional. HTML input type used to render the current field's child options. 2328 * @since BuddyPress (2.0.0) 2329 */ 2330 public function admin_new_field_html( BP_XProfile_Field $current_field, $control_type = '' ) {} 2331 } 2332 2333 /** 2334 * Textbox xprofile field type. 2335 * 2336 * @since BuddyPress (2.0.0) 2337 */ 2338 class BP_XProfile_Field_Type_Textbox extends BP_XProfile_Field_Type { 2339 2340 /** 2341 * Constructor for the textbox field type 2342 * 2343 * @since BuddyPress (2.0.0) 2344 */ 2345 public function __construct() { 2346 parent::__construct(); 2347 2348 $this->category = _x( 'Single Fields', 'xprofile field type category', 'buddypress' ); 2349 $this->name = _x( 'Text Box', 'xprofile field type', 'buddypress' ); 2350 2351 $this->set_format( '/^.*$/', 'replace' ); 2352 do_action( 'bp_xprofile_field_type_textbox', $this ); 2353 } 2354 2355 /** 2356 * Output the edit field HTML for this field type. 2357 * 2358 * Must be used inside the {@link bp_profile_fields()} template loop. 2359 * 2360 * @param array $raw_properties Optional key/value array of {@link http://dev.w3.org/html5/markup/input.text.html permitted attributes} that you want to add. 2361 * @since BuddyPress (2.0.0) 2362 */ 2363 public function edit_field_html( array $raw_properties = array() ) { 2364 2365 // user_id is a special optional parameter that certain other fields types pass to {@link bp_the_profile_field_options()}. 2366 if ( isset( $raw_properties['user_id'] ) ) { 2367 unset( $raw_properties['user_id'] ); 2368 } 2369 2370 $html = $this->get_edit_field_html_elements( array_merge( 2371 array( 2372 'type' => 'text', 2373 'value' => bp_get_the_profile_field_edit_value(), 2374 ), 2375 $raw_properties 2376 ) ); 2377 ?> 2378 <label for="<?php bp_the_profile_field_input_name(); ?>"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php _e( '(required)', 'buddypress' ); ?><?php endif; ?></label> 2379 <input <?php echo $html; ?>> 2380 <?php 2381 } 2382 2383 /** 2384 * Output HTML for this field type on the wp-admin Profile Fields screen. 2385 * 2386 * Must be used inside the {@link bp_profile_fields()} template loop. 2387 * 2388 * @param array $raw_properties Optional key/value array of permitted attributes that you want to add. 2389 * @since BuddyPress (2.0.0) 2390 */ 2391 public function admin_field_html( array $raw_properties = array() ) { 2392 $html = $this->get_edit_field_html_elements( array_merge( 2393 array( 'type' => 'text' ), 2394 $raw_properties 2395 ) ); 2396 ?> 2397 <input <?php echo $html; ?>> 2398 <?php 2399 } 2400 2401 /** 2402 * This method usually outputs HTML for this field type's children options on the wp-admin Profile Fields 2403 * "Add Field" and "Edit Field" screens, but for this field type, we don't want it, so it's stubbed out. 2404 * 2405 * @param BP_XProfile_Field $current_field The current profile field on the add/edit screen. 2406 * @param string $control_type Optional. HTML input type used to render the current field's child options. 2407 * @since BuddyPress (2.0.0) 2408 */ 2409 public function admin_new_field_html( BP_XProfile_Field $current_field, $control_type = '' ) {} 2410 } 2411 2412 /** 2413 * Number xprofile field type. 2414 * 2415 * @since BuddyPress (2.0.0) 2416 */ 2417 class BP_XProfile_Field_Type_Number extends BP_XProfile_Field_Type { 2418 2419 /** 2420 * Constructor for the number field type 2421 * 2422 * @since BuddyPress (2.0.0) 2423 */ 2424 public function __construct() { 2425 parent::__construct(); 2426 2427 $this->category = _x( 'Single Fields', 'xprofile field type category', 'buddypress' ); 2428 $this->name = _x( 'Number', 'xprofile field type', 'buddypress' ); 2429 2430 $this->set_format( '/^\d+$/', 'replace' ); 2431 do_action( 'bp_xprofile_field_type_number', $this ); 2432 } 2433 2434 /** 2435 * Output the edit field HTML for this field type. 2436 * 2437 * Must be used inside the {@link bp_profile_fields()} template loop. 2438 * 2439 * @param array $raw_properties Optional key/value array of {@link http://dev.w3.org/html5/markup/input.number.html permitted attributes} that you want to add. 2440 * @since BuddyPress (2.0.0) 2441 */ 2442 public function edit_field_html( array $raw_properties = array() ) { 2443 2444 // user_id is a special optional parameter that certain other fields types pass to {@link bp_the_profile_field_options()}. 2445 if ( isset( $raw_properties['user_id'] ) ) { 2446 unset( $raw_properties['user_id'] ); 2447 } 2448 2449 $html = $this->get_edit_field_html_elements( array_merge( 2450 array( 2451 'type' => 'number', 2452 'value' => bp_get_the_profile_field_edit_value(), 2453 ), 2454 $raw_properties 2455 ) ); 2456 ?> 2457 <label for="<?php bp_the_profile_field_input_name(); ?>"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php _e( '(required)', 'buddypress' ); ?><?php endif; ?></label> 2458 <input <?php echo $html; ?>> 2459 <?php 2460 } 2461 2462 /** 2463 * Output HTML for this field type on the wp-admin Profile Fields screen. 2464 * 2465 * Must be used inside the {@link bp_profile_fields()} template loop. 2466 * 2467 * @param array $raw_properties Optional key/value array of permitted attributes that you want to add. 2468 * @since BuddyPress (2.0.0) 2469 */ 2470 public function admin_field_html( array $raw_properties = array() ) { 2471 $html = $this->get_edit_field_html_elements( array_merge( 2472 array( 'type' => 'number' ), 2473 $raw_properties 2474 ) ); 2475 ?> 2476 <input <?php echo $html; ?>> 2477 <?php 2478 } 2479 2480 /** 2481 * This method usually outputs HTML for this field type's children options on the wp-admin Profile Fields 2482 * "Add Field" and "Edit Field" screens, but for this field type, we don't want it, so it's stubbed out. 2483 * 2484 * @param BP_XProfile_Field $current_field The current profile field on the add/edit screen. 2485 * @param string $control_type Optional. HTML input type used to render the current field's child options. 2486 * @since BuddyPress (2.0.0) 2487 */ 2488 public function admin_new_field_html( BP_XProfile_Field $current_field, $control_type = '' ) {} 2489 } 2490 2491 /** 2492 * Represents a type of XProfile field and holds meta information about the type of value that it accepts. 2493 * 2494 * @since BuddyPress (2.0.0) 2495 */ 2496 abstract class BP_XProfile_Field_Type { 2497 2498 /** 2499 * @since BuddyPress (2.0.0) 2500 * @var array Field type validation regexes 2501 */ 2502 protected $validation_regex = array(); 2503 2504 /** 2505 * @since BuddyPress (2.0.0) 2506 * @var array Field type whitelisted values 2507 */ 2508 protected $validation_whitelist = array(); 2509 2510 /** 2511 * @since BuddyPress (2.0.0) 2512 * @var string The name of this field type 2513 */ 2514 public $name = ''; 2515 2516 /** 2517 * The name of the category that this field type should be grouped with. Used on the [Users > Profile Fields] screen in wp-admin. 2518 * 2519 * @since BuddyPress (2.0.0) 2520 * @var string 2521 */ 2522 public $category = ''; 2523 2524 /** 2525 * @since BuddyPress (2.0.0) 2526 * @var bool If this is set, allow BP to store null/empty values for this field type. 2527 */ 2528 public $accepts_null_value = false; 2529 2530 /** 2531 * If this is set, BP will set this field type's validation whitelist from the field's options (e.g checkbox, selectbox). 2532 * 2533 * @since BuddyPress (2.0.0) 2534 * @var bool Does this field support options? e.g. selectbox, radio buttons, etc. 2535 */ 2536 public $supports_options = false; 2537 2538 /** 2539 * @since BuddyPress (2.0.0) 2540 * @var bool Does this field type support multiple options being set as default values? e.g. multiselectbox, checkbox. 2541 */ 2542 public $supports_multiple_defaults = false; 2543 2544 /** 2545 * @since BuddyPress (2.0.0) 2546 * @var BP_XProfile_Field If this object is created by instantiating a {@link BP_XProfile_Field}, this is a reference back to that object. 2547 */ 2548 public $field_obj = null; 2549 2550 /** 2551 * Constructor 2552 * 2553 * @since BuddyPress (2.0.0) 2554 */ 2555 public function __construct() { 2556 do_action( 'bp_xprofile_field_type', $this ); 2557 } 2558 2559 /** 2560 * Set a regex that profile data will be asserted against. 2561 * 2562 * You can call this method multiple times to set multiple formats. When validation is performed, 2563 * it's successful as long as the new value matches any one of the registered formats. 2564 * 2565 * @param string $format Regex string 2566 * @param string $replace_format Optional; if 'replace', replaces the format instead of adding to it. Defaults to 'add'. 2567 * @return BP_XProfile_Field_Type 2568 * @since BuddyPress (2.0.0) 2569 */ 2570 public function set_format( $format, $replace_format = 'add' ) { 2571 2572 $format = apply_filters( 'bp_xprofile_field_type_set_format', $format, $replace_format, $this ); 2573 2574 if ( $replace_format === 'add' ) { 2575 $this->validation_regex[] = $format; 2576 } elseif ( $replace_format === 'replace' ) { 2577 $this->validation_regex = array( $format ); 2578 } 2579 2580 return $this; 2581 } 2582 2583 /** 2584 * Add a value to this type's whitelist that that profile data will be asserted against. 2585 * 2586 * You can call this method multiple times to set multiple formats. When validation is performed, 2587 * it's successful as long as the new value matches any one of the registered formats. 2588 * 2589 * @param string|array $values 2590 * @return BP_XProfile_Field_Type 2591 * @since BuddyPress (2.0.0) 2592 */ 2593 public function set_whitelist_values( $values ) { 2594 foreach ( (array) $values as $value ) { 2595 $this->validation_whitelist[] = apply_filters( 'bp_xprofile_field_type_set_whitelist_values', $value, $values, $this ); 2596 } 2597 2598 return $this; 2599 } 2600 2601 /** 2602 * Check the given string against the registered formats for this field type. 2603 * 2604 * This method doesn't support chaining. 2605 * 2606 * @param string|array $values Value to check against the registered formats 2607 * @return bool True if the value validates 2608 * @since BuddyPress (2.0.0) 2609 */ 2610 public function is_valid( $values ) { 2611 $validated = false; 2612 2613 // Some types of field (e.g. multi-selectbox) may have multiple values to check 2614 foreach ( (array) $values as $value ) { 2615 2616 // Validate the $value against the type's accepted format(s). 2617 foreach ( $this->validation_regex as $format ) { 2618 if ( 1 === preg_match( $format, $value ) ) { 2619 $validated = true; 2620 continue; 2621 2622 } else { 2623 $validated = false; 2624 } 2625 } 2626 } 2627 2628 // Handle field types with accepts_null_value set if $values is an empty array 2629 if ( ! $validated && is_array( $values ) && empty( $values ) && $this->accepts_null_value ) { 2630 $validated = true; 2631 } 2632 2633 // If there's a whitelist set, also check the $value. 2634 if ( $validated && ! empty( $values ) && ! empty( $this->validation_whitelist ) ) { 2635 2636 foreach ( (array) $values as $value ) { 2637 $validated = in_array( $value, $this->validation_whitelist, true ); 2638 } 2639 } 2640 2641 return (bool) apply_filters( 'bp_xprofile_field_type_is_valid', $validated, $values, $this ); 2642 } 2643 2644 /** 2645 * Output the edit field HTML for this field type. 2646 * 2647 * Must be used inside the {@link bp_profile_fields()} template loop. 2648 * 2649 * @param array $raw_properties Optional key/value array of permitted attributes that you want to add. 2650 * @since BuddyPress (2.0.0) 2651 */ 2652 abstract public function edit_field_html( array $raw_properties = array() ); 2653 2654 /** 2655 * Output the edit field options HTML for this field type. 2656 * 2657 * BuddyPress considers a field's "options" to be, for example, the items in a selectbox. 2658 * These are stored seperately in the database, and their templating is handled seperately. 2659 * Populate this method in a child class if it's required. Otherwise, you can leave it out. 2660 * 2661 * This templating is seperate from {@link BP_XProfile_Field_Type::edit_field_html()} because 2662 * it's also used in the wp-admin screens when creating new fields, and for backwards compatibility. 2663 * 2664 * Must be used inside the {@link bp_profile_fields()} template loop. 2665 * 2666 * @param array $args Optional. The arguments passed to {@link bp_the_profile_field_options()}. 2667 * @since BuddyPress (2.0.0) 2668 */ 2669 public function edit_field_options_html( array $args = array() ) {} 2670 2671 /** 2672 * Output HTML for this field type on the wp-admin Profile Fields screen. 2673 * 2674 * Must be used inside the {@link bp_profile_fields()} template loop. 2675 * 2676 * @param array $raw_properties Optional key/value array of permitted attributes that you want to add. 2677 * @since BuddyPress (2.0.0) 2678 */ 2679 abstract public function admin_field_html( array $raw_properties = array() ); 2680 2681 /** 2682 * Output HTML for this field type's children options on the wp-admin Profile Fields "Add Field" and "Edit Field" screens. 2683 * 2684 * You don't need to implement this method for all field types. It's used in core by the 2685 * selectbox, multi selectbox, checkbox, and radio button fields, to allow the admin to 2686 * enter the child option values (e.g. the choices in a select box). 2687 * 2688 * Must be used inside the {@link bp_profile_fields()} template loop. 2689 * 2690 * @param BP_XProfile_Field $current_field The current profile field on the add/edit screen. 2691 * @param string $control_type Optional. HTML input type used to render the current field's child options. 2692 * @since BuddyPress (2.0.0) 2693 */ 2694 public function admin_new_field_html( BP_XProfile_Field $current_field, $control_type = '' ) { 2695 $type = array_search( get_class( $this ), bp_xprofile_get_field_types() ); 2696 if ( $type === false ) { 2697 return; 2698 } 2699 2700 $class = $current_field->type != $type ? 'display: none;' : ''; 2701 $current_type_obj = bp_xprofile_create_field_type( $type ); 2702 ?> 2703 2704 <div id="<?php echo esc_attr( $type ); ?>" class="postbox bp-options-box" style="<?php echo esc_attr( $class ); ?> margin-top: 15px;"> 2705 <h3><?php _e( 'Please enter options for this Field:', 'buddypress' ); ?></h3> 2706 <div class="inside"> 2707 <p> 2708 <label for="sort_order_<?php echo esc_attr( $type ); ?>"><?php _e( 'Sort Order:', 'buddypress' ); ?></label> 2709 <select name="sort_order_<?php echo esc_attr( $type ); ?>" id="sort_order_<?php echo esc_attr( $type ); ?>" > 2710 <option value="custom" <?php selected( 'custom', $current_field->order_by ); ?>><?php _e( 'Custom', 'buddypress' ); ?></option> 2711 <option value="asc" <?php selected( 'asc', $current_field->order_by ); ?>><?php _e( 'Ascending', 'buddypress' ); ?></option> 2712 <option value="desc" <?php selected( 'desc', $current_field->order_by ); ?>><?php _e( 'Descending', 'buddypress' ); ?></option> 2713 </select> 2714 </p> 2715 2716 <?php 2717 $options = $current_field->get_children( true ); 2718 2719 // If no children options exists for this field, check in $_POST for a submitted form (e.g. on the "new field" screen). 2720 if ( ! $options ) { 2721 2722 $options = array(); 2723 $i = 1; 2724 2725 while ( isset( $_POST[$type . '_option'][$i] ) ) { 2726 2727 // Multiselectbox and checkboxes support MULTIPLE default options; all other core types support only ONE. 2728 if ( $current_type_obj->supports_options && ! $current_type_obj->supports_multiple_defaults && isset( $_POST["isDefault_{$type}_option"][$i] ) && (int) $_POST["isDefault_{$type}_option"] === $i ) { 2729 $is_default_option = true; 2730 } elseif ( isset( $_POST["isDefault_{$type}_option"][$i] ) ) { 2731 $is_default_option = (bool) $_POST["isDefault_{$type}_option"][$i]; 2732 } else { 2733 $is_default_option = false; 2734 } 2735 2736 // Grab the values from $_POST to use as the form's options 2737 $options[] = (object) array( 2738 'id' => -1, 2739 'is_default_option' => $is_default_option, 2740 'name' => sanitize_text_field( stripslashes( $_POST[$type . '_option'][$i] ) ), 2741 ); 2742 2743 ++$i; 2744 } 2745 2746 // If there are still no children options set, this must be the "new field" screen, so add one new/empty option. 2747 if ( ! $options ) { 2748 $options[] = (object) array( 2749 'id' => -1, 2750 'is_default_option' => false, 2751 'name' => '', 2752 ); 2753 } 2754 } 2755 2756 // Render the markup for the children options 2757 if ( ! empty( $options ) ) { 2758 $default_name = ''; 2759 2760 for ( $i = 0, $count = count( $options ); $i < $count; ++$i ) : 2761 $j = $i + 1; 2762 2763 // Multiselectbox and checkboxes support MULTIPLE default options; all other core types support only ONE. 2764 if ( $current_type_obj->supports_options && $current_type_obj->supports_multiple_defaults ) { 2765 $default_name = '[' . $j . ']'; 2766 } 2767 ?> 2768 2769 <p class="sortable"> 2770 <span> Ξ </span> 2771 <input type="text" name="<?php echo esc_attr( "{$type}_option[{$j}]" ); ?>" id="<?php echo esc_attr( "{$type}_option{$j}" ); ?>" value="<?php echo esc_attr( $options[$i]->name ); ?>" /> 2772 <input type="<?php echo esc_attr( $control_type ); ?>" name="<?php echo esc_attr( "isDefault_{$type}_option{$default_name}" ); ?>" <?php checked( $options[$i]->is_default_option, true ); ?> value="<?php echo esc_attr( $j ); ?>" /> 2773 <span><?php _e( 'Default Value', 'buddypress' ); ?></span> 2774 <a href="<?php echo esc_url( 'users.php?page=bp-profile-setup&mode=delete_option&option_id=' . $options[$i]->id ); ?>" class="ajax-option-delete" id="<?php echo esc_attr( "delete-{$options[$i]->id}" ); ?>">[x]</a> 2775 </p> 2776 <?php endfor; ?> 2777 2778 <input type="hidden" name="<?php echo esc_attr( "{$type}_option_number" ); ?>" id="<?php echo esc_attr( "{$type}_option_number" ); ?>" value="<?php echo esc_attr( $j + 1 ); ?>" /> 2779 <?php } ?> 2780 2781 <div id="<?php echo esc_attr( "{$type}_more" ); ?>"></div> 2782 <p><a href="javascript:add_option('<?php echo esc_js( $type ); ?>')"><?php _e( 'Add Another Option', 'buddypress' ); ?></a></p> 2783 </div> 2784 </div> 2785 2786 <?php 2787 } 2788 2789 2790 /** 2791 * Internal protected/private helper methods past this point. 2792 */ 2793 2794 /** 2795 * Get a sanitised and escaped string of the edit field's HTML elements and attributes. 2796 * 2797 * Must be used inside the {@link bp_profile_fields()} template loop. 2798 * This method was intended to be static but couldn't be because php.net/lsb/ requires PHP >= 5.3. 2799 * 2800 * @param array $properties Optional key/value array of attributes for this edit field. 2801 * @return string 2802 * @since BuddyPress (2.0.0) 2803 */ 2804 protected function get_edit_field_html_elements( array $properties = array() ) { 2805 2806 $properties = array_merge( array( 2807 'id' => bp_get_the_profile_field_input_name(), 2808 'name' => bp_get_the_profile_field_input_name(), 2809 ), $properties ); 2810 2811 if ( bp_get_the_profile_field_is_required() ) { 2812 $properties['aria-required'] = 'true'; 2813 } 2814 2815 $html = ''; 2816 $properties = (array) apply_filters( 'bp_xprofile_field_edit_html_elements', $properties, get_class( $this ) ); 2817 2818 foreach ( $properties as $name => $value ) { 2819 $html .= sprintf( '%s="%s" ', sanitize_key( $name ), esc_attr( $value ) ); 2820 } 2821 2822 return $html; 2823 } 2824 } -
bp-xprofile/bp-xprofile-functions.php
diff --git bp-xprofile/bp-xprofile-functions.php bp-xprofile/bp-xprofile-functions.php index cd116fd..466ba30 100644
function xprofile_update_field_group_position( $field_group_id, $position ) { 60 60 61 61 /*** Field Management *********************************************************/ 62 62 63 /** 64 * Get details of all xprofile field types. 65 * 66 * @return array Key/value pairs (field type => class name). 67 * @since BuddyPress (2.0.0) 68 */ 69 function bp_xprofile_get_field_types() { 70 $fields = array( 71 'checkbox' => 'BP_XProfile_Field_Type_Checkbox', 72 'datebox' => 'BP_XProfile_Field_Type_Datebox', 73 'multiselectbox' => 'BP_XProfile_Field_Type_Multiselectbox', 74 'number' => 'BP_XProfile_Field_Type_Number', 75 'radio' => 'BP_XProfile_Field_Type_Radiobutton', 76 'selectbox' => 'BP_XProfile_Field_Type_Selectbox', 77 'textarea' => 'BP_XProfile_Field_Type_Textarea', 78 'textbox' => 'BP_XProfile_Field_Type_Textbox', 79 ); 80 81 // If you've added a custom field type in a plugin, register it with this filter. 82 return apply_filters( 'bp_xprofile_get_field_types', $fields ); 83 } 84 85 /** 86 * Creates the specified field type object; used for validation and templating. 87 * 88 * @param string $type Type of profile field to create. See {@link bp_xprofile_get_field_types()} for default core values. 89 * @return object If field type unknown, returns BP_XProfile_Field_Type_Textarea. Otherwise returns an instance of the relevant child class of BP_XProfile_Field_Type. 90 * @since BuddyPress (2.0.0) 91 */ 92 function bp_xprofile_create_field_type( $type ) { 93 94 $field = bp_xprofile_get_field_types(); 95 $class = isset( $field[$type] ) ? $field[$type] : ''; 96 97 /** 98 * For backpat and to handle (missing) field types introduced by other plugins, fallback to 99 * textbox if a type is unknown. Textbox validation and display is intentionally low key. 100 */ 101 if ( $class && class_exists( $class ) ) { 102 return new $class; 103 } else { 104 return new BP_XProfile_Field_Type_Textbox; 105 } 106 } 107 63 108 function xprofile_insert_field( $args = '' ) { 64 109 global $bp; 65 110 … … function xprofile_set_field_data( $field, $user_id, $value, $is_required = false 214 259 if ( $is_required && ( empty( $value ) || !is_array( $value ) && !strlen( trim( $value ) ) ) ) 215 260 return false; 216 261 217 $field = new BP_XProfile_Field( $field_id ); 262 $field = new BP_XProfile_Field( $field_id ); 263 $field_type_obj = bp_xprofile_create_field_type( BP_XProfile_Field::get_type( $field_id ) ); 218 264 219 // If the value is empty, then delete any field data that exists, unless the field is of a 220 // type where null values are semantically meaningful 221 if ( empty( $value ) && 'checkbox' != $field->type && 'multiselectbox' != $field->type ) { 265 // If the value is empty, then delete any field data that exists, unless the field is of a type where null values are semantically meaningful 266 if ( empty( $value ) && ! $field_type_obj->accepts_null_value ) { 222 267 xprofile_delete_field_data( $field_id, $user_id ); 223 268 return true; 224 269 } 225 270 226 $possible_values = array(); 227 228 // Check the value is an acceptable value 229 if ( 'checkbox' == $field->type || 'radio' == $field->type || 'selectbox' == $field->type || 'multiselectbox' == $field->type ) { 230 $options = $field->get_children(); 231 232 foreach( $options as $option ) 233 $possible_values[] = $option->name; 234 235 if ( is_array( $value ) ) { 236 foreach( $value as $i => $single ) { 237 if ( !in_array( $single, $possible_values ) ) { 238 unset( $value[$i] ); 239 } 240 } 271 // For certain fields, only certain parameters are acceptable, so add them to the whitelist. 272 if ( $field_type_obj->supports_options ) { 273 $field_type_obj->set_whitelist_values( wp_list_pluck( $field->get_children(), 'name' ) ); 274 } 241 275 242 // Reset the keys by merging with an empty array 243 $value = array_merge( array(), $value ); 244 } else { 245 if ( !in_array( $value, $possible_values ) ) { 246 return false; 247 } 248 } 276 // Check the value is in an accepted format for this form field. 277 if ( ! $field_type_obj->is_valid( $value ) ) { 278 return false; 249 279 } 250 280 251 281 $field = new BP_XProfile_ProfileData(); -
bp-xprofile/bp-xprofile-loader.php
diff --git bp-xprofile/bp-xprofile-loader.php bp-xprofile/bp-xprofile-loader.php index 922877c..3477fe1 100644
class BP_XProfile_Component extends BP_Component { 98 98 } 99 99 100 100 // Set the support field type ids 101 $this->field_types = apply_filters( 'xprofile_field_types', array( 102 'textbox', 103 'textarea', 104 'radio', 105 'checkbox', 106 'selectbox', 107 'multiselectbox', 108 'datebox' 109 ) ); 101 $this->field_types = apply_filters( 'xprofile_field_types', array_keys( bp_xprofile_get_field_types() ) ); 110 102 111 103 // Register the visibility levels. See bp_xprofile_get_visibility_levels() to filter 112 104 $this->visibility_levels = array( -
bp-xprofile/bp-xprofile-template.php
diff --git bp-xprofile/bp-xprofile-template.php bp-xprofile/bp-xprofile-template.php index ff320d9..65e2360 100644
function bp_field_css_class( $class = false ) { 221 221 if ( $profile_template->current_field % 2 == 1 ) 222 222 $css_classes[] = 'alt'; 223 223 224 $css_classes[] = 'field_type_' . sanitize_title( $profile_template->field->type ); 224 225 $css_classes = apply_filters_ref_array( 'bp_field_css_classes', array( &$css_classes ) ); 225 226 226 227 return apply_filters( 'bp_get_field_css_class', ' class="' . implode( ' ', $css_classes ) . '"' ); … … function bp_the_profile_field_input_name() { 386 387 function bp_get_the_profile_field_input_name() { 387 388 global $field; 388 389 389 $array_box = false; 390 if ( 'multiselectbox' == $field->type ) 391 $array_box = '[]'; 392 393 return apply_filters( 'bp_get_the_profile_field_input_name', 'field_' . $field->id . $array_box ); 390 return apply_filters( 'bp_get_the_profile_field_input_name', 'field_' . $field->id ); 394 391 } 395 392 396 393 /** … … function bp_get_the_profile_field_errors_action() { 423 420 * 424 421 * @param array $args Specify type for datebox. Allowed 'day', 'month', 'year'. 425 422 */ 426 function bp_the_profile_field_options( $args = '') {423 function bp_the_profile_field_options( $args = array() ) { 427 424 echo bp_get_the_profile_field_options( $args ); 428 425 } 429 426 /** 430 427 * bp_get_the_profile_field_options() 431 428 * 432 * Retrieves field options HTML for field types of 'selectbox', 'multiselectbox', 433 * 'radio', 'checkbox', and 'datebox'. 429 * Retrieves field options HTML for field types of 'selectbox', 'multiselectbox', 'radio', 'checkbox', and 'datebox'. 434 430 * 435 431 * @package BuddyPress Xprofile 436 432 * @since BuddyPress (1.1) … … function bp_the_profile_field_options( $args = '' ) { 446 442 * used when rendering options. Default: displayed user. 447 443 * } 448 444 */ 449 function bp_get_the_profile_field_options( $args = '') {445 function bp_get_the_profile_field_options( $args = array() ) { 450 446 global $field; 451 447 452 $ defaults =array(448 $args = wp_parse_args( $args, array( 453 449 'type' => false, 454 450 'user_id' => bp_displayed_user_id(), 455 ); 456 457 $r = wp_parse_args( $args, $defaults ); 458 extract( $r, EXTR_SKIP ); 451 ) ); 459 452 460 // In some cases, the $field global is not an instantiation of the BP_XProfile_Field 461 // class. However, we have to make sure that all data originally in $field gets 462 // merged back in, after reinstantiation. 463 if ( !method_exists( $field, 'get_children' ) ) { 453 /** 454 * In some cases, the $field global is not an instantiation of the BP_XProfile_Field class. 455 * However, we have to make sure that all data originally in $field gets merged back in, after reinstantiation. 456 */ 457 if ( ! method_exists( $field, 'get_children' ) ) { 464 458 $field_obj = new BP_XProfile_Field( $field->id ); 465 459 466 foreach ( $field as $field_prop => $field_prop_value ) {467 if ( ! isset( $field_obj->{$field_prop} ) ) {460 foreach ( $field as $field_prop => $field_prop_value ) { 461 if ( ! isset( $field_obj->{$field_prop} ) ) 468 462 $field_obj->{$field_prop} = $field_prop_value; 469 }470 463 } 471 464 472 465 $field = $field_obj; 473 466 } 474 467 475 $options = $field->get_children(); 476 477 // Setup some defaults 478 $html = ''; 479 $selected = ''; 480 481 switch ( $field->type ) { 482 case 'selectbox': 483 484 $html .= '<option value="">' . /* translators: no option picked in select box */ __( '----', 'buddypress' ) . '</option>'; 485 486 $original_option_values = ''; 487 $original_option_values = maybe_unserialize( BP_XProfile_ProfileData::get_value_byid( $field->id, $user_id ) ); 488 489 if ( empty( $original_option_values ) && !empty( $_POST['field_' . $field->id] ) ) { 490 $original_option_values = $_POST['field_' . $field->id]; 491 } 492 493 $option_values = (array) $original_option_values; 494 495 for ( $k = 0, $count = count( $options ); $k < $count; ++$k ) { 496 497 // Check for updated posted values, but errors preventing them from being saved first time 498 foreach( $option_values as $i => $option_value ) { 499 if ( isset( $_POST['field_' . $field->id] ) && $_POST['field_' . $field->id] != $option_value ) { 500 if ( !empty( $_POST['field_' . $field->id] ) ) { 501 $option_values[$i] = $_POST['field_' . $field->id]; 502 } 503 } 504 } 505 506 $selected = ''; 507 508 // Run the allowed option name through the before_save filter, so we'll be sure to get a match 509 $allowed_options = xprofile_sanitize_data_value_before_save( $options[$k]->name, false, false ); 510 511 // First, check to see whether the user-entered value matches 512 if ( in_array( $allowed_options, (array) $option_values ) ) { 513 $selected = ' selected="selected"'; 514 } 515 516 // Then, if the user has not provided a value, check for defaults 517 if ( !is_array( $original_option_values ) && empty( $option_values ) && $options[$k]->is_default_option ) { 518 $selected = ' selected="selected"'; 519 } 520 521 $html .= apply_filters( 'bp_get_the_profile_field_options_select', '<option' . $selected . ' value="' . esc_attr( stripslashes( $options[$k]->name ) ) . '">' . esc_attr( stripslashes( $options[$k]->name ) ) . '</option>', $options[$k], $field->id, $selected, $k ); 522 } 523 break; 524 525 case 'multiselectbox': 526 $original_option_values = ''; 527 $original_option_values = maybe_unserialize( BP_XProfile_ProfileData::get_value_byid( $field->id, $user_id ) ); 528 529 if ( empty( $original_option_values ) && !empty( $_POST['field_' . $field->id] ) ) { 530 $original_option_values = $_POST['field_' . $field->id]; 531 } 532 533 $option_values = (array) $original_option_values; 534 535 for ( $k = 0, $count = count( $options ); $k < $count; ++$k ) { 536 537 // Check for updated posted values, but errors preventing them from being saved first time 538 foreach( $option_values as $i => $option_value ) { 539 if ( isset( $_POST['field_' . $field->id] ) && $_POST['field_' . $field->id][$i] != $option_value ) { 540 if ( !empty( $_POST['field_' . $field->id][$i] ) ) { 541 $option_values[] = $_POST['field_' . $field->id][$i]; 542 } 543 } 544 } 545 $selected = ''; 546 547 // Run the allowed option name through the before_save filter, so we'll be sure to get a match 548 $allowed_options = xprofile_sanitize_data_value_before_save( $options[$k]->name, false, false ); 549 550 // First, check to see whether the user-entered value matches 551 if ( in_array( $allowed_options, (array) $option_values ) ) { 552 $selected = ' selected="selected"'; 553 } 554 555 // Then, if the user has not provided a value, check for defaults 556 if ( !is_array( $original_option_values ) && empty( $option_values ) && !empty( $options[$k]->is_default_option ) ) { 557 $selected = ' selected="selected"'; 558 } 559 560 $html .= apply_filters( 'bp_get_the_profile_field_options_multiselect', '<option' . $selected . ' value="' . esc_attr( stripslashes( $options[$k]->name ) ) . '">' . esc_attr( stripslashes( $options[$k]->name ) ) . '</option>', $options[$k], $field->id, $selected, $k ); 561 } 562 break; 563 564 case 'radio': 565 $html .= '<div id="field_' . $field->id . '">'; 566 $option_value = BP_XProfile_ProfileData::get_value_byid( $field->id, $user_id ); 567 568 for ( $k = 0, $count = count( $options ); $k < $count; ++$k ) { 569 570 // Check for updated posted values, but errors preventing them from being saved first time 571 if ( isset( $_POST['field_' . $field->id] ) && $option_value != $_POST['field_' . $field->id] ) { 572 if ( !empty( $_POST['field_' . $field->id] ) ) { 573 $option_value = $_POST['field_' . $field->id]; 574 } 575 } 576 577 // Run the allowed option name through the before_save 578 // filter, so we'll be sure to get a match 579 $allowed_options = xprofile_sanitize_data_value_before_save( $options[$k]->name, false, false ); 580 $selected = ''; 581 582 if ( $option_value == $allowed_options || ( empty( $option_value ) && !empty( $options[$k]->is_default_option ) ) ) 583 $selected = ' checked="checked"'; 584 585 $html .= apply_filters( 'bp_get_the_profile_field_options_radio', '<label><input' . $selected . ' type="radio" name="field_' . $field->id . '" id="option_' . $options[$k]->id . '" value="' . esc_attr( stripslashes( $options[$k]->name ) ) . '"> ' . esc_attr( stripslashes( $options[$k]->name ) ) . '</label>', $options[$k], $field->id, $selected, $k ); 586 } 587 588 $html .= '</div>'; 589 break; 590 591 case 'checkbox': 592 $option_values = BP_XProfile_ProfileData::get_value_byid( $field->id, $user_id ); 593 $option_values = (array) maybe_unserialize( $option_values ); 594 595 // Check for updated posted values, but errors preventing them from being saved first time 596 if ( isset( $_POST['field_' . $field->id] ) && $option_values != maybe_serialize( $_POST['field_' . $field->id] ) ) { 597 if ( !empty( $_POST['field_' . $field->id] ) ) 598 $option_values = $_POST['field_' . $field->id]; 599 } 600 601 for ( $k = 0, $count = count( $options ); $k < $count; ++$k ) { 602 $selected = ''; 603 604 // First, check to see whether the user's saved values 605 // match the option 606 for ( $j = 0, $count_values = count( $option_values ); $j < $count_values; ++$j ) { 607 608 // Run the allowed option name through the 609 // before_save filter, so we'll be sure to get a match 610 $allowed_options = xprofile_sanitize_data_value_before_save( $options[$k]->name, false, false ); 611 612 if ( $option_values[$j] == $allowed_options || @in_array( $allowed_options, $option_values ) ) { 613 $selected = ' checked="checked"'; 614 break; 615 } 616 } 617 618 // If the user has not yet supplied a value for this field, 619 // check to see whether there is a default value available 620 if ( !is_array( $option_values ) && empty( $option_values ) && empty( $selected ) && !empty( $options[$k]->is_default_option ) ) { 621 $selected = ' checked="checked"'; 622 } 623 624 $html .= apply_filters( 'bp_get_the_profile_field_options_checkbox', '<label><input' . $selected . ' type="checkbox" name="field_' . $field->id . '[]" id="field_' . $options[$k]->id . '_' . $k . '" value="' . esc_attr( stripslashes( $options[$k]->name ) ) . '"> ' . esc_attr( stripslashes( $options[$k]->name ) ) . '</label>', $options[$k], $field->id, $selected, $k ); 625 } 626 break; 627 628 case 'datebox': 629 $date = BP_XProfile_ProfileData::get_value_byid( $field->id, $user_id ); 630 631 // Set day, month, year defaults 632 $day = ''; 633 $month = ''; 634 $year = ''; 635 636 if ( !empty( $date ) ) { 637 638 // If Unix timestamp 639 if ( is_numeric( $date ) ) { 640 $day = date( 'j', $date ); 641 $month = date( 'F', $date ); 642 $year = date( 'Y', $date ); 643 644 // If MySQL timestamp 645 } else { 646 $day = mysql2date( 'j', $date ); 647 $month = mysql2date( 'F', $date, false ); // Not localized, so that selected() works below 648 $year = mysql2date( 'Y', $date ); 649 } 650 } 651 652 // Check for updated posted values, and errors preventing 653 // them from being saved first time. 654 if ( !empty( $_POST['field_' . $field->id . '_day'] ) ) { 655 if ( $day != $_POST['field_' . $field->id . '_day'] ) { 656 $day = $_POST['field_' . $field->id . '_day']; 657 } 658 } 659 660 if ( !empty( $_POST['field_' . $field->id . '_month'] ) ) { 661 if ( $month != $_POST['field_' . $field->id . '_month'] ) { 662 $month = $_POST['field_' . $field->id . '_month']; 663 } 664 } 665 666 if ( !empty( $_POST['field_' . $field->id . '_year'] ) ) { 667 if ( $year != date( "j", $_POST['field_' . $field->id . '_year'] ) ) { 668 $year = $_POST['field_' . $field->id . '_year']; 669 } 670 } 671 672 // $type will be passed by calling function when needed 673 switch ( $type ) { 674 case 'day': 675 $html .= '<option value=""' . selected( $day, '', false ) . '>--</option>'; 676 677 for ( $i = 1; $i < 32; ++$i ) { 678 $html .= '<option value="' . $i .'"' . selected( $day, $i, false ) . '>' . $i . '</option>'; 679 } 680 break; 681 682 case 'month': 683 $eng_months = array( 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ); 684 685 $months = array( 686 __( 'January', 'buddypress' ), 687 __( 'February', 'buddypress' ), 688 __( 'March', 'buddypress' ), 689 __( 'April', 'buddypress' ), 690 __( 'May', 'buddypress' ), 691 __( 'June', 'buddypress' ), 692 __( 'July', 'buddypress' ), 693 __( 'August', 'buddypress' ), 694 __( 'September', 'buddypress' ), 695 __( 'October', 'buddypress' ), 696 __( 'November', 'buddypress' ), 697 __( 'December', 'buddypress' ) 698 ); 699 700 $html .= '<option value=""' . selected( $month, '', false ) . '>------</option>'; 701 702 for ( $i = 0; $i < 12; ++$i ) { 703 $html .= '<option value="' . $eng_months[$i] . '"' . selected( $month, $eng_months[$i], false ) . '>' . $months[$i] . '</option>'; 704 } 705 break; 706 707 case 'year': 708 $html .= '<option value=""' . selected( $year, '', false ) . '>----</option>'; 709 710 for ( $i = 2037; $i > 1901; $i-- ) { 711 $html .= '<option value="' . $i .'"' . selected( $year, $i, false ) . '>' . $i . '</option>'; 712 } 713 break; 714 } 715 716 $html = apply_filters( 'bp_get_the_profile_field_datebox', $html, $type, $day, $month, $year, $field->id, $date ); 717 718 break; 719 } 468 ob_start(); 469 $field->type_obj->edit_field_options_html( $args ); 470 $html = ob_get_contents(); 471 ob_end_clean(); 720 472 721 473 return $html; 722 474 } … … function bp_xprofile_settings_visibility_select( $args = '' ) { 1014 766 1015 767 // Output the dropdown list 1016 768 return apply_filters( 'bp_xprofile_settings_visibility_select', ob_get_clean() ); 1017 } 1018 No newline at end of file 769 } -
new file tests/testcases/xprofile/class-bp-xprofile-field-type.php
diff --git tests/testcases/xprofile/class-bp-xprofile-field-type.php tests/testcases/xprofile/class-bp-xprofile-field-type.php new file mode 100644 index 0000000..67138cb
- + 1 <?php 2 /** 3 * @group xprofile 4 * @group BP_XProfile_Field_Type 5 */ 6 class BP_Tests_XProfile_Field_Type extends BP_UnitTestCase { 7 public function setUp() { 8 parent::setUp(); 9 } 10 11 public function tearDown() { 12 parent::tearDown(); 13 } 14 15 public function test_unregistered_field_type_returns_textbox() { 16 $field = bp_xprofile_create_field_type( 'fakeyfield' ); 17 $this->assertEquals( get_class( $field ), 'BP_XProfile_Field_Type_Textbox' ); 18 } 19 20 21 public function test_textbox_validate_string() { 22 $field = bp_xprofile_create_field_type( 'textbox' ); 23 $this->assertTrue( $field->is_valid( 'my 117th input string!' ) ); 24 } 25 26 public function test_textbox_validate_integer() { 27 $field = bp_xprofile_create_field_type( 'textbox' ); 28 $this->assertTrue( $field->is_valid( 123 ) ); 29 } 30 31 public function test_textbox_validate_whitelisted_string() { 32 $field = bp_xprofile_create_field_type( 'textbox' ); 33 34 $this->assertTrue( $field->is_valid( 'a string' ) ); 35 $this->assertFalse( $field->set_whitelist_values( 'pizza' )->is_valid( 'pasta' ) ); 36 $this->assertTrue( $field->is_valid( 'pizza' ) ); 37 } 38 39 40 public function test_multiselectbox_validate_whitelisted_array() { 41 $field = bp_xprofile_create_field_type( 'multiselectbox' ); 42 $field->set_whitelist_values( array( 'cheese', 'pepporoni' ) ); 43 44 $this->assertTrue( $field->is_valid( array( 'cheese', 'pepporoni' ) ) ); 45 $this->assertTrue( $field->is_valid( array( 'cheese' ) ) ); 46 $this->assertFalse( $field->is_valid( array( 'cheese', 'pepporoni', 'pinapple' ) ) ); 47 $this->assertFalse( $field->is_valid( array( 'pinapple' ) ) ); 48 } 49 50 public function test_multiselectbox_validate_null_value() { 51 $field = bp_xprofile_create_field_type( 'multiselectbox' ); 52 $field->set_whitelist_values( array( 'cheese', 'pepporoni' ) ); 53 54 $this->assertFalse( $field->is_valid( array( '' ) ) ); 55 $this->assertFalse( $field->is_valid( '' ) ); 56 $this->assertTrue( $field->is_valid( array() ) ); 57 } 58 59 60 public function test_datebox_do_not_validate_string() { 61 $field = bp_xprofile_create_field_type( 'datebox' ); 62 $this->assertFalse( $field->is_valid( 'datebox fields only accept strings in: Y-m-d 00:00:00' ) ); 63 } 64 65 public function test_datebox_do_not_validate_integer() { 66 $field = bp_xprofile_create_field_type( 'datebox' ); 67 $this->assertFalse( $field->is_valid( 221213 ) ); 68 } 69 70 public function test_datebox_validate_date() { 71 $field = bp_xprofile_create_field_type( 'datebox' ); 72 $this->assertTrue( $field->is_valid( '2013-12-22 00:00:00' ) ); 73 } 74 75 public function test_datebox_do_not_validate_date_with_timestamp() { 76 $field = bp_xprofile_create_field_type( 'datebox' ); 77 $this->assertFalse( $field->is_valid( '2013-12-22 19:11:30' ) ); 78 $this->assertFalse( $field->is_valid( '2013-12-22' ) ); 79 } 80 81 82 public function test_number_do_not_validate_string() { 83 $field = bp_xprofile_create_field_type( 'number' ); 84 $this->assertFalse( $field->is_valid( 'telephone fields only accept integers' ) ); 85 } 86 87 public function test_number_validate_integer() { 88 $field = bp_xprofile_create_field_type( 'number' ); 89 $this->assertTrue( $field->is_valid( 12345678901 ) ); 90 } 91 92 93 public function test_radiobutton_validate_whitelisted_array() { 94 $field = bp_xprofile_create_field_type( 'radio' ); 95 $field->set_whitelist_values( array( 'cheese', 'pepporoni' ) ); 96 97 $this->assertTrue( $field->is_valid( array( 'cheese', 'pepporoni' ) ) ); 98 $this->assertTrue( $field->is_valid( array( 'cheese' ) ) ); 99 $this->assertFalse( $field->is_valid( array( 'cheese', 'pepporoni', 'pinapple' ) ) ); 100 $this->assertFalse( $field->is_valid( array( 'pinapple' ) ) ); 101 } 102 103 public function test_radiobutton_do_not_validate_empty_items_in_whitelist() { 104 $field = bp_xprofile_create_field_type( 'radio' ); 105 $field->set_whitelist_values( array( '' ) ); 106 107 $this->assertFalse( $field->is_valid( array( '' ) ) ); 108 } 109 110 111 public function test_checkbox_validate_whitelisted_array() { 112 $field = bp_xprofile_create_field_type( 'checkbox' ); 113 $field->set_whitelist_values( array( 'cheese', 'pepporoni' ) ); 114 115 $this->assertTrue( $field->is_valid( array( 'cheese', 'pepporoni' ) ) ); 116 $this->assertTrue( $field->is_valid( array( 'cheese' ) ) ); 117 $this->assertFalse( $field->is_valid( array( 'cheese', 'pepporoni', 'pinapple' ) ) ); 118 $this->assertFalse( $field->is_valid( array( 'pinapple' ) ) ); 119 } 120 121 public function test_checkbox_validate_null_value() { 122 $field = bp_xprofile_create_field_type( 'checkbox' ); 123 $field->set_whitelist_values( array( 'cheese', 'pepporoni' ) ); 124 125 $this->assertFalse( $field->is_valid( array( '' ) ) ); 126 $this->assertFalse( $field->is_valid( '' ) ); 127 $this->assertTrue( $field->is_valid( array() ) ); 128 } 129 }