Ticket #5220: 5220.04.patch
File 5220.04.patch, 121.5 KB (added by , 11 years ago) |
---|
-
bp-members/admin/css/admin.css
diff --git a/bp-members/admin/css/admin.css b/bp-members/admin/css/admin.css index 5473fe5..5d295da 100644
a b 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 a/bp-templates/bp-legacy/buddypress/members/register.php b/bp-templates/bp-legacy/buddypress/members/register.php index 8679dc2..6624817 100644
a b 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 a/bp-templates/bp-legacy/buddypress/members/single/profile/edit.php b/bp-templates/bp-legacy/buddypress/members/single/profile/edit.php index b7b6cc5..a20c079 100644
a b 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 a/bp-templates/bp-legacy/css/buddypress.css b/bp-templates/bp-legacy/css/buddypress.css index befd22c..773519a 100644
a b 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 a/bp-xprofile/bp-xprofile-admin.php b/bp-xprofile/bp-xprofile-admin.php index 1c275db..eca6366 100644
a b 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 { 642 636 // Set the errors var 643 637 $errors = false; 644 638 645 // Now we've checked for required fields, let s save the values.639 // Now we've checked for required fields, let's save the values. 646 640 foreach ( (array) $posted_field_ids as $field_id ) { 647 641 648 642 // 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 { 702 696 } 703 697 704 698 if ( bp_has_profile( $r ) ) : 705 706 699 while ( bp_profile_groups() ) : bp_the_profile_group(); ?> 700 <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() ); ?>" /> 707 701 708 <p class="description"><?php bp_the_profile_group_description(); ?></p> 709 710 <table class="form-table"> 711 <tbody> 712 713 <?php while ( bp_profile_fields() ) : bp_the_profile_field(); ?> 714 715 <tr> 716 717 <?php if ( 'textbox' === bp_get_the_profile_field_type() ) : ?> 702 <?php if ( bp_get_the_profile_group_description() ) : ?> 703 <p class="description"><?php bp_the_profile_group_description(); ?></p> 704 <?php 705 endif; 718 706 719 <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> 720 <td class="admin-field-<?php bp_the_profile_field_type();?>"> 721 <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; ?>/> 722 <span class="description"><?php bp_the_profile_field_description(); ?></span> 723 </td> 707 while ( bp_profile_fields() ) : bp_the_profile_field(); ?> 724 708 725 <?php endif; ?> 726 727 <?php if ( 'textarea' === bp_get_the_profile_field_type() ) : ?> 709 <div<?php bp_field_css_class( 'bp-profile-field' ); ?>> 710 <?php 711 $field_type = bp_xprofile_create_field_type( bp_get_the_profile_field_type() ); 712 $field_type->edit_field_html( array( 'user_id' => $r['user_id'] ) ); 728 713 729 <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> 730 <td class="admin-field-<?php bp_the_profile_field_type();?>"> 731 <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> 732 <p class="description"><?php bp_the_profile_field_description(); ?></p> 733 </td> 734 735 <?php endif; ?> 714 if ( bp_get_the_profile_field_description() ) : ?> 715 <p class="description"><?php bp_the_profile_field_description(); ?></p> 716 <?php endif; 736 717 737 <?php if ( 'selectbox' === bp_get_the_profile_field_type() ) : ?> 718 do_action( 'bp_custom_profile_edit_fields_pre_visibility' ); 719 $can_change_visibility = bp_current_user_can( 'bp_xprofile_change_field_visibility' ); 720 ?> 738 721 739 <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> 740 <td class="admin-field-<?php bp_the_profile_field_type();?>"> 741 <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; ?>> 742 <?php bp_the_profile_field_options( array( 'user_id' => $r['user_id'], ) ); ?> 743 </select> 744 <span class="description"><?php bp_the_profile_field_description(); ?></span> 745 </td> 722 <p class="field-visibility-settings-<?php echo $can_change_visibility ? 'toggle' : 'notoggle'; ?>" id="field-visibility-settings-toggle-<?php bp_the_profile_field_id(); ?>"> 723 <?php 724 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() ); 746 725 726 if ( $can_change_visibility ) : ?> 727 <a href="#" class="button visibility-toggle-link"><?php _e( 'Change', 'buddypress' ); ?></a> 747 728 <?php endif; ?> 729 </p> 730 731 <?php if ( $can_change_visibility ) : ?> 732 <div class="field-visibility-settings" id="field-visibility-settings-<?php bp_the_profile_field_id() ?>"> 733 <fieldset> 734 <legend><?php _e( 'Who can see this field?', 'buddypress' ); ?></legend> 735 <?php bp_profile_visibility_radio_buttons(); ?> 736 </fieldset> 737 <a class="button field-visibility-settings-close" href="#"><?php _e( 'Close', 'buddypress' ); ?></a> 738 </div> 739 <?php endif; 748 740 749 <?php if ( 'multiselectbox' === bp_get_the_profile_field_type() ) : ?> 750 751 <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> 752 <td class="admin-field-<?php bp_the_profile_field_type();?>"> 753 <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; ?>> 754 755 <?php bp_the_profile_field_options( array( 'user_id' => $r['user_id'], ) ); ?> 756 757 </select> 758 759 760 <?php if ( !bp_get_the_profile_field_is_required() ) : ?> 761 762 <p><a class="clear-value" href="javascript:clear( '<?php bp_the_profile_field_input_name(); ?>' );"><?php _e( 'Clear', 'buddypress' ); ?></a></p> 763 764 <?php endif; ?> 765 <p class="description"><?php bp_the_profile_field_description(); ?></p> 766 </td> 767 768 <?php endif; ?> 769 770 <?php if ( 'radio' === bp_get_the_profile_field_type() ) : ?> 771 772 <th> 773 <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> 774 </th> 775 <td class="admin-field-<?php bp_the_profile_field_type();?>"> 776 <fieldset> 777 <legend class="screen-reader-text"><span><?php bp_the_profile_field_name(); ?></span></legend> 778 <?php bp_the_profile_field_options( array( 'user_id' => $r['user_id'], ) ); ?> 779 </fieldset> 780 781 <?php if ( !bp_get_the_profile_field_is_required() ) : ?> 782 783 <p><a class="clear-value" href="javascript:clear( '<?php bp_the_profile_field_input_name(); ?>' );"><?php _e( 'Clear', 'buddypress' ); ?></a></p> 784 785 <?php endif; ?> 786 <p class="description"><?php bp_the_profile_field_description(); ?></p> 787 </td> 788 789 <?php endif; ?> 790 791 <?php if ( 'checkbox' === bp_get_the_profile_field_type() ) : ?> 792 793 <th> 794 <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> 795 </th> 796 <td class="admin-field-<?php bp_the_profile_field_type();?>"> 797 <?php bp_the_profile_field_options( array( 'user_id' => $r['user_id'], ) ); ?> 798 <p class="description"><?php bp_the_profile_field_description(); ?></p> 799 </td> 800 801 <?php endif; ?> 802 803 <?php if ( 'datebox' === bp_get_the_profile_field_type() ) : ?> 804 805 <th> 806 <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> 807 </th> 808 <td class="admin-field-<?php bp_the_profile_field_type();?>"> 809 <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; ?>> 810 811 <?php bp_the_profile_field_options( array( 'user_id' => $r['user_id'], 'type' => 'day', ) ); ?> 812 813 </select> 814 815 <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; ?>> 816 817 <?php bp_the_profile_field_options( array( 'user_id' => $r['user_id'], 'type' => 'month', ) ); ?> 818 819 </select> 820 821 <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; ?>> 822 823 <?php bp_the_profile_field_options( array( 'user_id' => $r['user_id'], 'type' => 'year', ) ); ?> 824 825 </select> 826 <p class="description"><?php bp_the_profile_field_description(); ?></p> 827 </td> 828 829 <?php endif; ?> 830 831 </tr> 832 833 <tr class="admin-field-visibility-tr"> 834 <td class="admin-field-visibility-td"> </td> 835 <td class="admin-field-visibility-td"> 836 837 <?php do_action( 'bp_custom_profile_edit_fields_pre_visibility' ); ?> 838 839 <?php if ( bp_current_user_can( 'bp_xprofile_change_field_visibility' ) ) : ?> 840 <p class="description field-visibility-settings-toggle" id="field-visibility-settings-toggle-<?php bp_the_profile_field_id() ?>"> 841 <?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> 842 </p> 843 844 <div class="field-visibility-settings" id="field-visibility-settings-<?php bp_the_profile_field_id() ?>"> 845 <fieldset> 846 <legend><?php esc_html_e( 'Who can see this field?', 'buddypress' ) ?></legend> 847 848 <?php bp_profile_visibility_radio_buttons() ?> 849 850 </fieldset> 851 <a class="field-visibility-settings-close" href="#"><?php esc_html_e( 'Close', 'buddypress' ) ?></a> 852 </div> 853 <?php else : ?> 854 <div class="field-visibility-settings-notoggle" id="field-visibility-settings-toggle-<?php bp_the_profile_field_id() ?>"> 855 <?php printf( __( 'This field can be seen by: <span class="current-visibility-level">%s</span>', 'buddypress' ), bp_get_the_profile_field_visibility_level_label() ) ?> 856 </div> 857 <?php endif ?> 858 859 </td> 860 </tr> 741 do_action( 'bp_custom_profile_edit_fields' ); ?> 742 </div> 861 743 862 <?php endwhile; ?>863 </tbody>744 <?php 745 endwhile; // bp_profile_fields() 864 746 865 </table> 866 <input type="hidden" name="field_ids[]" id="field_ids_<?php bp_the_profile_group_slug(); ?>" value="<?php bp_the_profile_group_field_ids(); ?>" /> 867 <?php endwhile; 747 endwhile; // bp_profile_groups() 868 748 endif; 869 749 } 870 750 -
bp-xprofile/bp-xprofile-classes.php
diff --git a/bp-xprofile/bp-xprofile-classes.php b/bp-xprofile/bp-xprofile-classes.php index 18e7724..4deff29 100644
a b 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 esc_html_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 separately in the database, and their templating is handled seperately. 1535 * 1536 * This templating is separate 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 esc_html_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 separately in the database, and their templating is handled seperately. 1748 * 1749 * This templating is separate 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 esc_html_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 esc_html_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 separately in the database, and their templating is handled seperately. 1889 * 1890 * This templating is separate 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 esc_html_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( 2010 'multiple' => 'multiple', 2011 'id' => bp_get_the_profile_field_input_name() . '[]', 2012 'name' => bp_get_the_profile_field_input_name() . '[]', 2013 ), 2014 $raw_properties 2015 ) ); 2016 ?> 2017 <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> 2018 <select <?php echo $html; ?>> 2019 <?php bp_the_profile_field_options( "user_id={$user_id}" ); ?> 2020 </select> 2021 2022 <?php if ( ! bp_get_the_profile_field_is_required() ) : ?> 2023 <a class="clear-value" href="javascript:clear( '<?php echo esc_js( bp_get_the_profile_field_input_name() ); ?>[]' );"><?php esc_html_e( 'Clear', 'buddypress' ); ?></a> 2024 <?php endif; ?> 2025 <?php 2026 } 2027 2028 /** 2029 * Output the edit field options HTML for this field type. 2030 * 2031 * BuddyPress considers a field's "options" to be, for example, the items in a selectbox. 2032 * These are stored separately in the database, and their templating is handled seperately. 2033 * 2034 * This templating is separate from {@link BP_XProfile_Field_Type::edit_field_html()} because 2035 * it's also used in the wp-admin screens when creating new fields, and for backwards compatibility. 2036 * 2037 * Must be used inside the {@link bp_profile_fields()} template loop. 2038 * 2039 * @param array $args Optional. The arguments passed to {@link bp_the_profile_field_options()}. 2040 * @since BuddyPress (2.0.0) 2041 */ 2042 public function edit_field_options_html( array $args = array() ) { 2043 $original_option_values = maybe_unserialize( BP_XProfile_ProfileData::get_value_byid( $this->field_obj->id, $args['user_id'] ) ); 2044 2045 $options = $this->field_obj->get_children(); 2046 $html = ''; 2047 2048 if ( empty( $original_option_values ) && ! empty( $_POST['field_' . $this->field_obj->id] ) ) { 2049 $original_option_values = sanitize_text_field( $_POST['field_' . $this->field_obj->id] ); 2050 } 2051 2052 $option_values = (array) $original_option_values; 2053 for ( $k = 0, $count = count( $options ); $k < $count; ++$k ) { 2054 $selected = ''; 2055 2056 // Check for updated posted values, but errors preventing them from being saved first time 2057 foreach( $option_values as $i => $option_value ) { 2058 if ( isset( $_POST['field_' . $this->field_obj->id] ) && $_POST['field_' . $this->field_obj->id][$i] != $option_value ) { 2059 if ( ! empty( $_POST['field_' . $this->field_obj->id][$i] ) ) { 2060 $option_values[] = sanitize_text_field( $_POST['field_' . $this->field_obj->id][$i] ); 2061 } 2062 } 2063 } 2064 2065 // Run the allowed option name through the before_save filter, so we'll be sure to get a match 2066 $allowed_options = xprofile_sanitize_data_value_before_save( $options[$k]->name, false, false ); 2067 2068 // First, check to see whether the user-entered value matches 2069 if ( in_array( $allowed_options, $option_values ) ) { 2070 $selected = ' selected="selected"'; 2071 } 2072 2073 // Then, if the user has not provided a value, check for defaults 2074 if ( ! is_array( $original_option_values ) && empty( $option_values ) && ! empty( $options[$k]->is_default_option ) ) { 2075 $selected = ' selected="selected"'; 2076 } 2077 2078 $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 ); 2079 } 2080 2081 echo $html; 2082 } 2083 2084 /** 2085 * Output HTML for this field type on the wp-admin Profile Fields screen. 2086 * 2087 * Must be used inside the {@link bp_profile_fields()} template loop. 2088 * 2089 * @param array $raw_properties Optional key/value array of permitted attributes that you want to add. 2090 * @since BuddyPress (2.0.0) 2091 */ 2092 public function admin_field_html( array $raw_properties = array() ) { 2093 $html = $this->get_edit_field_html_elements( array_merge( 2094 array( 'multiple' => 'multiple' ), 2095 $raw_properties 2096 ) ); 2097 ?> 2098 <select <?php echo $html; ?>> 2099 <?php bp_the_profile_field_options(); ?> 2100 </select> 2101 <?php 2102 } 2103 2104 /** 2105 * Output HTML for this field type's children options on the wp-admin Profile Fields "Add Field" and "Edit Field" screens. 2106 * 2107 * Must be used inside the {@link bp_profile_fields()} template loop. 2108 * 2109 * @param BP_XProfile_Field $current_field The current profile field on the add/edit screen. 2110 * @param string $control_type Optional. HTML input type used to render the current field's child options. 2111 * @since BuddyPress (2.0.0) 2112 */ 2113 public function admin_new_field_html( BP_XProfile_Field $current_field, $control_type = '' ) { 2114 parent::admin_new_field_html( $current_field, 'checkbox' ); 2115 } 2116 } 2117 2118 /** 2119 * Selectbox xprofile field type. 2120 * 2121 * @since BuddyPress (2.0.0) 2122 */ 2123 class BP_XProfile_Field_Type_Selectbox extends BP_XProfile_Field_Type { 2124 2125 /** 2126 * Constructor for the selectbox field type 2127 * 2128 * @since BuddyPress (2.0.0) 2129 */ 2130 public function __construct() { 2131 parent::__construct(); 2132 2133 $this->category = _x( 'Multi Fields', 'xprofile field type category', 'buddypress' ); 2134 $this->name = _x( 'Drop Down Select Box', 'xprofile field type', 'buddypress' ); 2135 2136 $this->supports_options = true; 2137 2138 $this->set_format( '/^.+$/', 'replace' ); 2139 do_action( 'bp_xprofile_field_type_selectbox', $this ); 2140 } 2141 2142 /** 2143 * Output the edit field HTML for this field type. 2144 * 2145 * Must be used inside the {@link bp_profile_fields()} template loop. 2146 * 2147 * @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. 2148 * @since BuddyPress (2.0.0) 2149 */ 2150 public function edit_field_html( array $raw_properties = array() ) { 2151 $user_id = bp_displayed_user_id(); 2152 2153 // user_id is a special optional parameter that we pass to {@link bp_the_profile_field_options()}. 2154 if ( isset( $raw_properties['user_id'] ) ) { 2155 $user_id = (int) $raw_properties['user_id']; 2156 unset( $raw_properties['user_id'] ); 2157 } 2158 2159 $html = $this->get_edit_field_html_elements( $raw_properties ); 2160 ?> 2161 <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 esc_html_e( '(required)', 'buddypress' ); ?><?php endif; ?></label> 2162 <select <?php echo $html; ?>> 2163 <?php bp_the_profile_field_options( "user_id={$user_id}" ); ?> 2164 </select> 2165 <?php 2166 } 2167 2168 /** 2169 * Output the edit field options HTML for this field type. 2170 * 2171 * BuddyPress considers a field's "options" to be, for example, the items in a selectbox. 2172 * These are stored separately in the database, and their templating is handled seperately. 2173 * 2174 * This templating is separate from {@link BP_XProfile_Field_Type::edit_field_html()} because 2175 * it's also used in the wp-admin screens when creating new fields, and for backwards compatibility. 2176 * 2177 * Must be used inside the {@link bp_profile_fields()} template loop. 2178 * 2179 * @param array $args Optional. The arguments passed to {@link bp_the_profile_field_options()}. 2180 * @since BuddyPress (2.0.0) 2181 */ 2182 public function edit_field_options_html( array $args = array() ) { 2183 $original_option_values = maybe_unserialize( BP_XProfile_ProfileData::get_value_byid( $this->field_obj->id, $args['user_id'] ) ); 2184 2185 $options = $this->field_obj->get_children(); 2186 $html = '<option value="">' . /* translators: no option picked in select box */ esc_html__( '----', 'buddypress' ) . '</option>'; 2187 2188 if ( empty( $original_option_values ) && !empty( $_POST['field_' . $this->field_obj->id] ) ) { 2189 $original_option_values = sanitize_text_field( $_POST['field_' . $this->field_obj->id] ); 2190 } 2191 2192 $option_values = (array) $original_option_values; 2193 for ( $k = 0, $count = count( $options ); $k < $count; ++$k ) { 2194 $selected = ''; 2195 2196 // Check for updated posted values, but errors preventing them from being saved first time 2197 foreach( $option_values as $i => $option_value ) { 2198 if ( isset( $_POST['field_' . $this->field_obj->id] ) && $_POST['field_' . $this->field_obj->id] != $option_value ) { 2199 if ( ! empty( $_POST['field_' . $this->field_obj->id] ) ) { 2200 $option_values[$i] = sanitize_text_field( $_POST['field_' . $this->field_obj->id] ); 2201 } 2202 } 2203 } 2204 2205 // Run the allowed option name through the before_save filter, so we'll be sure to get a match 2206 $allowed_options = xprofile_sanitize_data_value_before_save( $options[$k]->name, false, false ); 2207 2208 // First, check to see whether the user-entered value matches 2209 if ( in_array( $allowed_options, $option_values ) ) { 2210 $selected = ' selected="selected"'; 2211 } 2212 2213 // Then, if the user has not provided a value, check for defaults 2214 if ( ! is_array( $original_option_values ) && empty( $option_values ) && $options[$k]->is_default_option ) { 2215 $selected = ' selected="selected"'; 2216 } 2217 2218 $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 ); 2219 } 2220 2221 echo $html; 2222 } 2223 2224 /** 2225 * Output HTML for this field type on the wp-admin Profile Fields screen. 2226 * 2227 * Must be used inside the {@link bp_profile_fields()} template loop. 2228 * 2229 * @param array $raw_properties Optional key/value array of permitted attributes that you want to add. 2230 * @since BuddyPress (2.0.0) 2231 */ 2232 public function admin_field_html( array $raw_properties = array() ) { 2233 $html = $this->get_edit_field_html_elements( $raw_properties ); 2234 ?> 2235 <select <?php echo $html; ?>> 2236 <?php bp_the_profile_field_options(); ?> 2237 </select> 2238 <?php 2239 } 2240 2241 /** 2242 * Output HTML for this field type's children options on the wp-admin Profile Fields "Add Field" and "Edit Field" screens. 2243 * 2244 * Must be used inside the {@link bp_profile_fields()} template loop. 2245 * 2246 * @param BP_XProfile_Field $current_field The current profile field on the add/edit screen. 2247 * @param string $control_type Optional. HTML input type used to render the current field's child options. 2248 * @since BuddyPress (2.0.0) 2249 */ 2250 public function admin_new_field_html( BP_XProfile_Field $current_field, $control_type = '' ) { 2251 parent::admin_new_field_html( $current_field, 'radio' ); 2252 } 2253 } 2254 2255 /** 2256 * Textarea xprofile field type. 2257 * 2258 * @since BuddyPress (2.0.0) 2259 */ 2260 class BP_XProfile_Field_Type_Textarea extends BP_XProfile_Field_Type { 2261 2262 /** 2263 * Constructor for the textarea field type 2264 * 2265 * @since BuddyPress (2.0.0) 2266 */ 2267 public function __construct() { 2268 parent::__construct(); 2269 2270 $this->category = _x( 'Single Fields', 'xprofile field type category', 'buddypress' ); 2271 $this->name = _x( 'Multi-line Text Area', 'xprofile field type', 'buddypress' ); 2272 2273 $this->set_format( '/^.*$/m', 'replace' ); 2274 do_action( 'bp_xprofile_field_type_textarea', $this ); 2275 } 2276 2277 /** 2278 * Output the edit field HTML for this field type. 2279 * 2280 * Must be used inside the {@link bp_profile_fields()} template loop. 2281 * 2282 * @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. 2283 * @since BuddyPress (2.0.0) 2284 */ 2285 public function edit_field_html( array $raw_properties = array() ) { 2286 2287 // user_id is a special optional parameter that certain other fields types pass to {@link bp_the_profile_field_options()}. 2288 if ( isset( $raw_properties['user_id'] ) ) { 2289 unset( $raw_properties['user_id'] ); 2290 } 2291 2292 $html = $this->get_edit_field_html_elements( array_merge( 2293 array( 2294 'cols' => 40, 2295 'rows' => 5, 2296 ), 2297 $raw_properties 2298 ) ); 2299 ?> 2300 <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 esc_html_e( '(required)', 'buddypress' ); ?><?php endif; ?></label> 2301 <textarea <?php echo $html; ?>><?php bp_the_profile_field_edit_value(); ?></textarea> 2302 <?php 2303 } 2304 2305 /** 2306 * Output HTML for this field type on the wp-admin Profile Fields screen. 2307 * 2308 * Must be used inside the {@link bp_profile_fields()} template loop. 2309 * 2310 * @param array $raw_properties Optional key/value array of permitted attributes that you want to add. 2311 * @since BuddyPress (2.0.0) 2312 */ 2313 public function admin_field_html( array $raw_properties = array() ) { 2314 $html = $this->get_edit_field_html_elements( array_merge( 2315 array( 2316 'cols' => 40, 2317 'rows' => 5, 2318 ), 2319 $raw_properties 2320 ) ); 2321 ?> 2322 <textarea <?php echo $html; ?>></textarea> 2323 <?php 2324 } 2325 2326 /** 2327 * This method usually outputs HTML for this field type's children options on the wp-admin Profile Fields 2328 * "Add Field" and "Edit Field" screens, but for this field type, we don't want it, so it's stubbed out. 2329 * 2330 * @param BP_XProfile_Field $current_field The current profile field on the add/edit screen. 2331 * @param string $control_type Optional. HTML input type used to render the current field's child options. 2332 * @since BuddyPress (2.0.0) 2333 */ 2334 public function admin_new_field_html( BP_XProfile_Field $current_field, $control_type = '' ) {} 2335 } 2336 2337 /** 2338 * Textbox xprofile field type. 2339 * 2340 * @since BuddyPress (2.0.0) 2341 */ 2342 class BP_XProfile_Field_Type_Textbox extends BP_XProfile_Field_Type { 2343 2344 /** 2345 * Constructor for the textbox field type 2346 * 2347 * @since BuddyPress (2.0.0) 2348 */ 2349 public function __construct() { 2350 parent::__construct(); 2351 2352 $this->category = _x( 'Single Fields', 'xprofile field type category', 'buddypress' ); 2353 $this->name = _x( 'Text Box', 'xprofile field type', 'buddypress' ); 2354 2355 $this->set_format( '/^.*$/', 'replace' ); 2356 do_action( 'bp_xprofile_field_type_textbox', $this ); 2357 } 2358 2359 /** 2360 * Output the edit field HTML for this field type. 2361 * 2362 * Must be used inside the {@link bp_profile_fields()} template loop. 2363 * 2364 * @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. 2365 * @since BuddyPress (2.0.0) 2366 */ 2367 public function edit_field_html( array $raw_properties = array() ) { 2368 2369 // user_id is a special optional parameter that certain other fields types pass to {@link bp_the_profile_field_options()}. 2370 if ( isset( $raw_properties['user_id'] ) ) { 2371 unset( $raw_properties['user_id'] ); 2372 } 2373 2374 $html = $this->get_edit_field_html_elements( array_merge( 2375 array( 2376 'type' => 'text', 2377 'value' => bp_get_the_profile_field_edit_value(), 2378 ), 2379 $raw_properties 2380 ) ); 2381 ?> 2382 <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 esc_html_e( '(required)', 'buddypress' ); ?><?php endif; ?></label> 2383 <input <?php echo $html; ?>> 2384 <?php 2385 } 2386 2387 /** 2388 * Output HTML for this field type on the wp-admin Profile Fields screen. 2389 * 2390 * Must be used inside the {@link bp_profile_fields()} template loop. 2391 * 2392 * @param array $raw_properties Optional key/value array of permitted attributes that you want to add. 2393 * @since BuddyPress (2.0.0) 2394 */ 2395 public function admin_field_html( array $raw_properties = array() ) { 2396 $html = $this->get_edit_field_html_elements( array_merge( 2397 array( 'type' => 'text' ), 2398 $raw_properties 2399 ) ); 2400 ?> 2401 <input <?php echo $html; ?>> 2402 <?php 2403 } 2404 2405 /** 2406 * This method usually outputs HTML for this field type's children options on the wp-admin Profile Fields 2407 * "Add Field" and "Edit Field" screens, but for this field type, we don't want it, so it's stubbed out. 2408 * 2409 * @param BP_XProfile_Field $current_field The current profile field on the add/edit screen. 2410 * @param string $control_type Optional. HTML input type used to render the current field's child options. 2411 * @since BuddyPress (2.0.0) 2412 */ 2413 public function admin_new_field_html( BP_XProfile_Field $current_field, $control_type = '' ) {} 2414 } 2415 2416 /** 2417 * Number xprofile field type. 2418 * 2419 * @since BuddyPress (2.0.0) 2420 */ 2421 class BP_XProfile_Field_Type_Number extends BP_XProfile_Field_Type { 2422 2423 /** 2424 * Constructor for the number field type 2425 * 2426 * @since BuddyPress (2.0.0) 2427 */ 2428 public function __construct() { 2429 parent::__construct(); 2430 2431 $this->category = _x( 'Single Fields', 'xprofile field type category', 'buddypress' ); 2432 $this->name = _x( 'Number', 'xprofile field type', 'buddypress' ); 2433 2434 $this->set_format( '/^\d+$/', 'replace' ); 2435 do_action( 'bp_xprofile_field_type_number', $this ); 2436 } 2437 2438 /** 2439 * Output the edit field HTML for this field type. 2440 * 2441 * Must be used inside the {@link bp_profile_fields()} template loop. 2442 * 2443 * @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. 2444 * @since BuddyPress (2.0.0) 2445 */ 2446 public function edit_field_html( array $raw_properties = array() ) { 2447 2448 // user_id is a special optional parameter that certain other fields types pass to {@link bp_the_profile_field_options()}. 2449 if ( isset( $raw_properties['user_id'] ) ) { 2450 unset( $raw_properties['user_id'] ); 2451 } 2452 2453 $html = $this->get_edit_field_html_elements( array_merge( 2454 array( 2455 'type' => 'number', 2456 'value' => bp_get_the_profile_field_edit_value(), 2457 ), 2458 $raw_properties 2459 ) ); 2460 ?> 2461 <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 esc_html_e( '(required)', 'buddypress' ); ?><?php endif; ?></label> 2462 <input <?php echo $html; ?>> 2463 <?php 2464 } 2465 2466 /** 2467 * Output HTML for this field type on the wp-admin Profile Fields screen. 2468 * 2469 * Must be used inside the {@link bp_profile_fields()} template loop. 2470 * 2471 * @param array $raw_properties Optional key/value array of permitted attributes that you want to add. 2472 * @since BuddyPress (2.0.0) 2473 */ 2474 public function admin_field_html( array $raw_properties = array() ) { 2475 $html = $this->get_edit_field_html_elements( array_merge( 2476 array( 'type' => 'number' ), 2477 $raw_properties 2478 ) ); 2479 ?> 2480 <input <?php echo $html; ?>> 2481 <?php 2482 } 2483 2484 /** 2485 * This method usually outputs HTML for this field type's children options on the wp-admin Profile Fields 2486 * "Add Field" and "Edit Field" screens, but for this field type, we don't want it, so it's stubbed out. 2487 * 2488 * @param BP_XProfile_Field $current_field The current profile field on the add/edit screen. 2489 * @param string $control_type Optional. HTML input type used to render the current field's child options. 2490 * @since BuddyPress (2.0.0) 2491 */ 2492 public function admin_new_field_html( BP_XProfile_Field $current_field, $control_type = '' ) {} 2493 } 2494 2495 /** 2496 * Represents a type of XProfile field and holds meta information about the type of value that it accepts. 2497 * 2498 * @since BuddyPress (2.0.0) 2499 */ 2500 abstract class BP_XProfile_Field_Type { 2501 2502 /** 2503 * @since BuddyPress (2.0.0) 2504 * @var array Field type validation regexes 2505 */ 2506 protected $validation_regex = array(); 2507 2508 /** 2509 * @since BuddyPress (2.0.0) 2510 * @var array Field type whitelisted values 2511 */ 2512 protected $validation_whitelist = array(); 2513 2514 /** 2515 * @since BuddyPress (2.0.0) 2516 * @var string The name of this field type 2517 */ 2518 public $name = ''; 2519 2520 /** 2521 * The name of the category that this field type should be grouped with. Used on the [Users > Profile Fields] screen in wp-admin. 2522 * 2523 * @since BuddyPress (2.0.0) 2524 * @var string 2525 */ 2526 public $category = ''; 2527 2528 /** 2529 * @since BuddyPress (2.0.0) 2530 * @var bool If this is set, allow BP to store null/empty values for this field type. 2531 */ 2532 public $accepts_null_value = false; 2533 2534 /** 2535 * If this is set, BP will set this field type's validation whitelist from the field's options (e.g checkbox, selectbox). 2536 * 2537 * @since BuddyPress (2.0.0) 2538 * @var bool Does this field support options? e.g. selectbox, radio buttons, etc. 2539 */ 2540 public $supports_options = false; 2541 2542 /** 2543 * @since BuddyPress (2.0.0) 2544 * @var bool Does this field type support multiple options being set as default values? e.g. multiselectbox, checkbox. 2545 */ 2546 public $supports_multiple_defaults = false; 2547 2548 /** 2549 * @since BuddyPress (2.0.0) 2550 * @var BP_XProfile_Field If this object is created by instantiating a {@link BP_XProfile_Field}, this is a reference back to that object. 2551 */ 2552 public $field_obj = null; 2553 2554 /** 2555 * Constructor 2556 * 2557 * @since BuddyPress (2.0.0) 2558 */ 2559 public function __construct() { 2560 do_action( 'bp_xprofile_field_type', $this ); 2561 } 2562 2563 /** 2564 * Set a regex that profile data will be asserted against. 2565 * 2566 * You can call this method multiple times to set multiple formats. When validation is performed, 2567 * it's successful as long as the new value matches any one of the registered formats. 2568 * 2569 * @param string $format Regex string 2570 * @param string $replace_format Optional; if 'replace', replaces the format instead of adding to it. Defaults to 'add'. 2571 * @return BP_XProfile_Field_Type 2572 * @since BuddyPress (2.0.0) 2573 */ 2574 public function set_format( $format, $replace_format = 'add' ) { 2575 2576 $format = apply_filters( 'bp_xprofile_field_type_set_format', $format, $replace_format, $this ); 2577 2578 if ( 'add' === $replace_format ) { 2579 $this->validation_regex[] = $format; 2580 } elseif ( 'replace' === $replace_format ) { 2581 $this->validation_regex = array( $format ); 2582 } 2583 2584 return $this; 2585 } 2586 2587 /** 2588 * Add a value to this type's whitelist that that profile data will be asserted against. 2589 * 2590 * You can call this method multiple times to set multiple formats. When validation is performed, 2591 * it's successful as long as the new value matches any one of the registered formats. 2592 * 2593 * @param string|array $values 2594 * @return BP_XProfile_Field_Type 2595 * @since BuddyPress (2.0.0) 2596 */ 2597 public function set_whitelist_values( $values ) { 2598 foreach ( (array) $values as $value ) { 2599 $this->validation_whitelist[] = apply_filters( 'bp_xprofile_field_type_set_whitelist_values', $value, $values, $this ); 2600 } 2601 2602 return $this; 2603 } 2604 2605 /** 2606 * Check the given string against the registered formats for this field type. 2607 * 2608 * This method doesn't support chaining. 2609 * 2610 * @param string|array $values Value to check against the registered formats 2611 * @return bool True if the value validates 2612 * @since BuddyPress (2.0.0) 2613 */ 2614 public function is_valid( $values ) { 2615 $validated = false; 2616 2617 // Some types of field (e.g. multi-selectbox) may have multiple values to check 2618 foreach ( (array) $values as $value ) { 2619 2620 // Validate the $value against the type's accepted format(s). 2621 foreach ( $this->validation_regex as $format ) { 2622 if ( 1 === preg_match( $format, $value ) ) { 2623 $validated = true; 2624 continue; 2625 2626 } else { 2627 $validated = false; 2628 } 2629 } 2630 } 2631 2632 // Handle field types with accepts_null_value set if $values is an empty array 2633 if ( ! $validated && is_array( $values ) && empty( $values ) && $this->accepts_null_value ) { 2634 $validated = true; 2635 } 2636 2637 // If there's a whitelist set, also check the $value. 2638 if ( $validated && ! empty( $values ) && ! empty( $this->validation_whitelist ) ) { 2639 2640 foreach ( (array) $values as $value ) { 2641 $validated = in_array( $value, $this->validation_whitelist, true ); 2642 } 2643 } 2644 2645 return (bool) apply_filters( 'bp_xprofile_field_type_is_valid', $validated, $values, $this ); 2646 } 2647 2648 /** 2649 * Output the edit field HTML for this field type. 2650 * 2651 * Must be used inside the {@link bp_profile_fields()} template loop. 2652 * 2653 * @param array $raw_properties Optional key/value array of permitted attributes that you want to add. 2654 * @since BuddyPress (2.0.0) 2655 */ 2656 abstract public function edit_field_html( array $raw_properties = array() ); 2657 2658 /** 2659 * Output the edit field options HTML for this field type. 2660 * 2661 * BuddyPress considers a field's "options" to be, for example, the items in a selectbox. 2662 * These are stored separately in the database, and their templating is handled separately. 2663 * Populate this method in a child class if it's required. Otherwise, you can leave it out. 2664 * 2665 * This templating is separate from {@link BP_XProfile_Field_Type::edit_field_html()} because 2666 * it's also used in the wp-admin screens when creating new fields, and for backwards compatibility. 2667 * 2668 * Must be used inside the {@link bp_profile_fields()} template loop. 2669 * 2670 * @param array $args Optional. The arguments passed to {@link bp_the_profile_field_options()}. 2671 * @since BuddyPress (2.0.0) 2672 */ 2673 public function edit_field_options_html( array $args = array() ) {} 2674 2675 /** 2676 * Output HTML for this field type on the wp-admin Profile Fields screen. 2677 * 2678 * Must be used inside the {@link bp_profile_fields()} template loop. 2679 * 2680 * @param array $raw_properties Optional key/value array of permitted attributes that you want to add. 2681 * @since BuddyPress (2.0.0) 2682 */ 2683 abstract public function admin_field_html( array $raw_properties = array() ); 2684 2685 /** 2686 * Output HTML for this field type's children options on the wp-admin Profile Fields "Add Field" and "Edit Field" screens. 2687 * 2688 * You don't need to implement this method for all field types. It's used in core by the 2689 * selectbox, multi selectbox, checkbox, and radio button fields, to allow the admin to 2690 * enter the child option values (e.g. the choices in a select box). 2691 * 2692 * Must be used inside the {@link bp_profile_fields()} template loop. 2693 * 2694 * @param BP_XProfile_Field $current_field The current profile field on the add/edit screen. 2695 * @param string $control_type Optional. HTML input type used to render the current field's child options. 2696 * @since BuddyPress (2.0.0) 2697 */ 2698 public function admin_new_field_html( BP_XProfile_Field $current_field, $control_type = '' ) { 2699 $type = array_search( get_class( $this ), bp_xprofile_get_field_types() ); 2700 if ( false === $type ) { 2701 return; 2702 } 2703 2704 $class = $current_field->type != $type ? 'display: none;' : ''; 2705 $current_type_obj = bp_xprofile_create_field_type( $type ); 2706 ?> 2707 2708 <div id="<?php echo esc_attr( $type ); ?>" class="postbox bp-options-box" style="<?php echo esc_attr( $class ); ?> margin-top: 15px;"> 2709 <h3><?php esc_html_e( 'Please enter options for this Field:', 'buddypress' ); ?></h3> 2710 <div class="inside"> 2711 <p> 2712 <label for="sort_order_<?php echo esc_attr( $type ); ?>"><?php esc_html_e( 'Sort Order:', 'buddypress' ); ?></label> 2713 <select name="sort_order_<?php echo esc_attr( $type ); ?>" id="sort_order_<?php echo esc_attr( $type ); ?>" > 2714 <option value="custom" <?php selected( 'custom', $current_field->order_by ); ?>><?php esc_html_e( 'Custom', 'buddypress' ); ?></option> 2715 <option value="asc" <?php selected( 'asc', $current_field->order_by ); ?>><?php esc_html_e( 'Ascending', 'buddypress' ); ?></option> 2716 <option value="desc" <?php selected( 'desc', $current_field->order_by ); ?>><?php esc_html_e( 'Descending', 'buddypress' ); ?></option> 2717 </select> 2718 </p> 2719 2720 <?php 2721 $options = $current_field->get_children( true ); 2722 2723 // If no children options exists for this field, check in $_POST for a submitted form (e.g. on the "new field" screen). 2724 if ( ! $options ) { 2725 2726 $options = array(); 2727 $i = 1; 2728 2729 while ( isset( $_POST[$type . '_option'][$i] ) ) { 2730 2731 // Multiselectbox and checkboxes support MULTIPLE default options; all other core types support only ONE. 2732 if ( $current_type_obj->supports_options && ! $current_type_obj->supports_multiple_defaults && isset( $_POST["isDefault_{$type}_option"][$i] ) && (int) $_POST["isDefault_{$type}_option"] === $i ) { 2733 $is_default_option = true; 2734 } elseif ( isset( $_POST["isDefault_{$type}_option"][$i] ) ) { 2735 $is_default_option = (bool) $_POST["isDefault_{$type}_option"][$i]; 2736 } else { 2737 $is_default_option = false; 2738 } 2739 2740 // Grab the values from $_POST to use as the form's options 2741 $options[] = (object) array( 2742 'id' => -1, 2743 'is_default_option' => $is_default_option, 2744 'name' => sanitize_text_field( stripslashes( $_POST[$type . '_option'][$i] ) ), 2745 ); 2746 2747 ++$i; 2748 } 2749 2750 // If there are still no children options set, this must be the "new field" screen, so add one new/empty option. 2751 if ( ! $options ) { 2752 $options[] = (object) array( 2753 'id' => -1, 2754 'is_default_option' => false, 2755 'name' => '', 2756 ); 2757 } 2758 } 2759 2760 // Render the markup for the children options 2761 if ( ! empty( $options ) ) { 2762 $default_name = ''; 2763 2764 for ( $i = 0, $count = count( $options ); $i < $count; ++$i ) : 2765 $j = $i + 1; 2766 2767 // Multiselectbox and checkboxes support MULTIPLE default options; all other core types support only ONE. 2768 if ( $current_type_obj->supports_options && $current_type_obj->supports_multiple_defaults ) { 2769 $default_name = '[' . $j . ']'; 2770 } 2771 ?> 2772 2773 <p class="sortable"> 2774 <span> Ξ </span> 2775 <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 ); ?>" /> 2776 <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 ); ?>" /> 2777 <span><?php _e( 'Default Value', 'buddypress' ); ?></span> 2778 </p> 2779 <?php endfor; ?> 2780 2781 <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 ); ?>" /> 2782 <?php } ?> 2783 2784 <div id="<?php echo esc_attr( "{$type}_more" ); ?>"></div> 2785 <p><a href="javascript:add_option('<?php echo esc_js( $type ); ?>')"><?php esc_html_e( 'Add Another Option', 'buddypress' ); ?></a></p> 2786 </div> 2787 </div> 2788 2789 <?php 2790 } 2791 2792 2793 /** 2794 * Internal protected/private helper methods past this point. 2795 */ 2796 2797 /** 2798 * Get a sanitised and escaped string of the edit field's HTML elements and attributes. 2799 * 2800 * Must be used inside the {@link bp_profile_fields()} template loop. 2801 * This method was intended to be static but couldn't be because php.net/lsb/ requires PHP >= 5.3. 2802 * 2803 * @param array $properties Optional key/value array of attributes for this edit field. 2804 * @return string 2805 * @since BuddyPress (2.0.0) 2806 */ 2807 protected function get_edit_field_html_elements( array $properties = array() ) { 2808 2809 $properties = array_merge( array( 2810 'id' => bp_get_the_profile_field_input_name(), 2811 'name' => bp_get_the_profile_field_input_name(), 2812 ), $properties ); 2813 2814 if ( bp_get_the_profile_field_is_required() ) { 2815 $properties['aria-required'] = 'true'; 2816 } 2817 2818 $html = ''; 2819 $properties = (array) apply_filters( 'bp_xprofile_field_edit_html_elements', $properties, get_class( $this ) ); 2820 2821 foreach ( $properties as $name => $value ) { 2822 $html .= sprintf( '%s="%s" ', sanitize_key( $name ), esc_attr( $value ) ); 2823 } 2824 2825 return $html; 2826 } 2827 } -
bp-xprofile/bp-xprofile-functions.php
diff --git a/bp-xprofile/bp-xprofile-functions.php b/bp-xprofile/bp-xprofile-functions.php index 4c508dc..2df82cd 100644
a b 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 a/bp-xprofile/bp-xprofile-loader.php b/bp-xprofile/bp-xprofile-loader.php index 922877c..3477fe1 100644
a b 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 a/bp-xprofile/bp-xprofile-template.php b/bp-xprofile/bp-xprofile-template.php index ff320d9..aa87a64 100644
a b 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 = bp_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 ), 'get_the_profile_field_options' ); 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 a/tests/testcases/xprofile/class-bp-xprofile-field-type.php b/tests/testcases/xprofile/class-bp-xprofile-field-type.php new file mode 100644 index 0000000..4511262
- + 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_empty_string() { 22 $field = bp_xprofile_create_field_type( 'textbox' ); 23 $this->assertTrue( $field->is_valid( '' ) ); 24 } 25 26 public function test_textbox_validate_string() { 27 $field = bp_xprofile_create_field_type( 'textbox' ); 28 $this->assertTrue( $field->is_valid( 'my 117th input string!' ) ); 29 } 30 31 public function test_textbox_validate_integer() { 32 $field = bp_xprofile_create_field_type( 'textbox' ); 33 $this->assertTrue( $field->is_valid( 123 ) ); 34 } 35 36 public function test_textbox_validate_whitelisted_string() { 37 $field = bp_xprofile_create_field_type( 'textbox' ); 38 39 $this->assertTrue( $field->is_valid( 'a string' ) ); 40 $this->assertFalse( $field->set_whitelist_values( 'pizza' )->is_valid( 'pasta' ) ); 41 $this->assertTrue( $field->is_valid( 'pizza' ) ); 42 } 43 44 45 public function test_multiselectbox_validate_whitelisted_array() { 46 $field = bp_xprofile_create_field_type( 'multiselectbox' ); 47 $field->set_whitelist_values( array( 'cheese', 'pepporoni' ) ); 48 49 $this->assertTrue( $field->is_valid( array( 'cheese', 'pepporoni' ) ) ); 50 $this->assertTrue( $field->is_valid( array( 'cheese' ) ) ); 51 $this->assertFalse( $field->is_valid( array( 'cheese', 'pepporoni', 'pinapple' ) ) ); 52 $this->assertFalse( $field->is_valid( array( 'pinapple' ) ) ); 53 } 54 55 public function test_multiselectbox_validate_null_value() { 56 $field = bp_xprofile_create_field_type( 'multiselectbox' ); 57 $field->set_whitelist_values( array( 'cheese', 'pepporoni' ) ); 58 59 $this->assertFalse( $field->is_valid( array( '' ) ) ); 60 $this->assertFalse( $field->is_valid( '' ) ); 61 $this->assertTrue( $field->is_valid( array() ) ); 62 } 63 64 65 public function test_datebox_do_not_validate_string() { 66 $field = bp_xprofile_create_field_type( 'datebox' ); 67 $this->assertFalse( $field->is_valid( 'datebox fields only accept strings in: Y-m-d 00:00:00' ) ); 68 $this->assertFalse( $field->is_valid( '' ) ); 69 } 70 71 public function test_datebox_do_not_validate_integer() { 72 $field = bp_xprofile_create_field_type( 'datebox' ); 73 $this->assertFalse( $field->is_valid( 221213 ) ); 74 } 75 76 public function test_datebox_validate_date() { 77 $field = bp_xprofile_create_field_type( 'datebox' ); 78 $this->assertTrue( $field->is_valid( '2013-12-22 00:00:00' ) ); 79 } 80 81 public function test_datebox_do_not_validate_date_with_timestamp() { 82 $field = bp_xprofile_create_field_type( 'datebox' ); 83 $this->assertFalse( $field->is_valid( '2013-12-22 19:11:30' ) ); 84 $this->assertFalse( $field->is_valid( '2013-12-22' ) ); 85 } 86 87 88 public function test_number_do_not_validate_string() { 89 $field = bp_xprofile_create_field_type( 'number' ); 90 $this->assertFalse( $field->is_valid( 'telephone fields only accept integers' ) ); 91 $this->assertFalse( $field->is_valid( '' ) ); 92 } 93 94 public function test_number_validate_integer() { 95 $field = bp_xprofile_create_field_type( 'number' ); 96 $this->assertTrue( $field->is_valid( 12345678901 ) ); 97 } 98 99 100 public function test_radiobutton_validate_whitelisted_array() { 101 $field = bp_xprofile_create_field_type( 'radio' ); 102 $field->set_whitelist_values( array( 'cheese', 'pepporoni' ) ); 103 104 $this->assertTrue( $field->is_valid( array( 'cheese', 'pepporoni' ) ) ); 105 $this->assertTrue( $field->is_valid( array( 'cheese' ) ) ); 106 $this->assertFalse( $field->is_valid( array( 'cheese', 'pepporoni', 'pinapple' ) ) ); 107 $this->assertFalse( $field->is_valid( array( 'pinapple' ) ) ); 108 $this->assertFalse( $field->is_valid( '' ) ); 109 } 110 111 public function test_radiobutton_do_not_validate_empty_items_in_whitelist() { 112 $field = bp_xprofile_create_field_type( 'radio' ); 113 $field->set_whitelist_values( array( '' ) ); 114 115 $this->assertFalse( $field->is_valid( array( '' ) ) ); 116 } 117 118 119 public function test_checkbox_validate_whitelisted_array() { 120 $field = bp_xprofile_create_field_type( 'checkbox' ); 121 $field->set_whitelist_values( array( 'cheese', 'pepporoni' ) ); 122 123 $this->assertTrue( $field->is_valid( array( 'cheese', 'pepporoni' ) ) ); 124 $this->assertTrue( $field->is_valid( array( 'cheese' ) ) ); 125 $this->assertFalse( $field->is_valid( array( 'cheese', 'pepporoni', 'pinapple' ) ) ); 126 $this->assertFalse( $field->is_valid( array( 'pinapple' ) ) ); 127 $this->assertFalse( $field->is_valid( '' ) ); 128 } 129 130 public function test_checkbox_validate_null_value() { 131 $field = bp_xprofile_create_field_type( 'checkbox' ); 132 $field->set_whitelist_values( array( 'cheese', 'pepporoni' ) ); 133 134 $this->assertFalse( $field->is_valid( array( '' ) ) ); 135 $this->assertFalse( $field->is_valid( '' ) ); 136 $this->assertTrue( $field->is_valid( array() ) ); 137 } 138 }