Skip to:
Content

BuddyPress.org

Ticket #5220: 5220.03.diff

File 5220.03.diff, 130.8 KB (added by imath, 6 years ago)
  • bp-members/admin/css/admin.css

     
    1515        width:100%;
    1616}
    1717
    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 
    2618div#community-profile-page ul#profile-nav {
    2719        border-bottom:solid 1px #ccc;
    2820        width:100%;
     
    10496        color:red;
    10597}
    10698
    107 div#community-profile-page .form-table td.admin-field-visibility-td {
    108         padding:5px 5px 15px 5px;
     99.alt {
     100        background: none;
    109101}
    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;
    113106}
    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;
    117109}
    118 
    119 div#community-profile-page .field-visibility-settings legend,
    120 div#community-profile-page .field-visibility-settings-notoggle {
     110.bp-profile-field p {
    121111        font-size: 14px;
    122         font-style: italic;
    123         color:#666;
    124112}
    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;
    129121}
    130122
    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;
    134128}
    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;
    139132}
    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 */
    142155        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

     
    6868
    6969                                                <div class="editfield">
    7070
    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();
    7274
    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' );
    7676
    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' ) ) : ?>
    15778                                                                <p class="field-visibility-settings-toggle" id="field-visibility-settings-toggle-<?php bp_the_profile_field_id() ?>">
    15879                                                                        <?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>
    15980                                                                </p>
  • bp-templates/bp-legacy/buddypress/members/single/profile/edit.php

     
    2121
    2222                        <div<?php bp_field_css_class( 'editfield' ); ?>>
    2323
    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();
    2527
    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                                do_action( 'bp_custom_profile_edit_fields_pre_visibility' );
     29                                ?>
    2830
    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' ); ?>
    117 
    11831                                <?php if ( bp_current_user_can( 'bp_xprofile_change_field_visibility' ) ) : ?>
    11932                                        <p class="field-visibility-settings-toggle" id="field-visibility-settings-toggle-<?php bp_the_profile_field_id() ?>">
    12033                                                <?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>
  • bp-templates/bp-legacy/css/buddypress.css

     
    607607        font-weight: bold;
    608608        margin: 15px 0 5px 0;
    609609}
    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 {
    612612        color: #888;
    613613        font-size: 100%;
    614614        font-weight: normal;
  • bp-xprofile/admin/js/admin.js

     
    7979        if ( !document.getElementById( id ) ) return false;
    8080
    8181        document.getElementById( id ).style.display = "none";
    82         document.getElementById( id ).value = '';
     82        // the field id is [fieldtype]option[iterator] and not [fieldtype]div[iterator]
     83        field_id = id.replace( 'div', 'option' );
     84        document.getElementById( field_id ).value = '';
    8385}
    8486
    8587var fixHelper = function(e, ui) {
  • bp-xprofile/admin/js/admin.min.js

     
    1 function add_option(g){var j=document.getElementById(g+"_more");var l=document.getElementById(g+"_option_number").value;var a=document.createElement("p");var h=document.createElement("input");var k=document.createElement("span");var e=document.createTextNode("\u00A0\u039E\u00A0");var b=document.createElement("input");var f=document.createElement("span");var d=document.createTextNode(" Default Value ");a.setAttribute("id",g+"_div"+l);a.setAttribute("class","sortable");h.setAttribute("type","text");h.setAttribute("name",g+"_option["+l+"]");h.setAttribute("id",g+"_option"+l);k.appendChild(e);if(g=="checkbox"||g=="multiselectbox"){b.setAttribute("type","checkbox");b.setAttribute("name","isDefault_"+g+"_option["+l+"]")}else{b.setAttribute("type","radio");b.setAttribute("name","isDefault_"+g+"_option")}b.setAttribute("value",l);f.appendChild(d);var c=document.createElement("a");var i=document.createTextNode("[x]");c.setAttribute("href","javascript:hide('"+g+"_div"+l+"')");c.setAttribute("class","delete");c.appendChild(i);a.appendChild(k);a.appendChild(h);a.appendChild(document.createTextNode(" "));a.appendChild(b);a.appendChild(f);a.appendChild(c);j.appendChild(a);enableSortableFieldOptions(g);document.getElementById(g+"_option"+l).focus();l++;document.getElementById(g+"_option_number").value=l}function show_options(a){document.getElementById("radio").style.display="none";document.getElementById("selectbox").style.display="none";document.getElementById("multiselectbox").style.display="none";document.getElementById("checkbox").style.display="none";if(a=="radio"){document.getElementById("radio").style.display=""}if(a=="selectbox"){document.getElementById("selectbox").style.display=""}if(a=="multiselectbox"){document.getElementById("multiselectbox").style.display=""}if(a=="checkbox"){document.getElementById("checkbox").style.display=""}}function hide(a){if(!document.getElementById(a)){return false}document.getElementById(a).style.display="none";document.getElementById(a).value=""}var fixHelper=function(b,a){a.children().each(function(){jQuery(this).width(jQuery(this).width())});return a};function enableSortableFieldOptions(a){if(jQuery("#"+a+" p.sortable").length>1){jQuery(".bp-options-box").sortable({items:"p.sortable",tolerance:"pointer",axis:"y",handle:"span"});jQuery(".sortable span").css("cursor","move")}}function destroySortableFieldOptions(){jQuery(".bp-options-box").sortable("destroy");jQuery(".sortable span").css("cursor","default")}jQuery(document).ready(function(){jQuery("#bp-xprofile-add-field #title").focus();jQuery("a.ajax-option-delete").on("click",function(){var d=this.id.split("-");d=d[1];jQuery.post(ajaxurl,{action:"xprofile_delete_option",cookie:encodeURIComponent(document.cookie),_wpnonce:jQuery("input#_wpnonce").val(),option_id:d},function(e){})});jQuery('[id^="sort_order_"]').change(function(){if(jQuery(this).val()!="custom"){destroySortableFieldOptions()}else{enableSortableFieldOptions(jQuery("#fieldtype :selected").val())}});jQuery("ul#field-group-tabs").show();jQuery("ul#field-group-tabs").sortable({cursor:"move",axis:"x",opacity:0.6,items:"li",tolerance:"pointer",update:function(){jQuery.post(ajaxurl,{action:"xprofile_reorder_groups",cookie:encodeURIComponent(document.cookie),_wpnonce_reorder_groups:jQuery("input#_wpnonce_reorder_groups").val(),group_order:jQuery(this).sortable("serialize")},function(d){})}}).disableSelection();jQuery("fieldset.field-group").sortable({cursor:"move",opacity:0.3,items:"fieldset",tolerance:"pointer",update:function(){jQuery.post(ajaxurl,{action:"xprofile_reorder_fields",cookie:encodeURIComponent(document.cookie),_wpnonce_reorder_fields:jQuery("input#_wpnonce_reorder_fields").val(),field_order:jQuery(this).sortable("serialize"),field_group_id:jQuery(this).attr("id")},function(d){})}}).disableSelection().css("cursor","move");enableSortableFieldOptions(jQuery("#fieldtype :selected").val());var b;var a=jQuery("#tabs").tabs();c(a);function c(d){b=jQuery("ul:first li",d).droppable({accept:".connectedSortable fieldset",hoverClass:"ui-state-hover",activeClass:"ui-state-acceptable",touch:"pointer",tolerance:"pointer",drop:function(g,h){var e=jQuery(this);var f=jQuery(e.find("a").attr("href")).find(".connectedSortable");jQuery(e).removeClass("drop-candidate");h.draggable.hide("slow",function(){d.tabs("option","active",b.index(e));jQuery(this).appendTo(f).show("slow").animate({opacity:"1"},500);f=jQuery(e.find("a").attr("href")).find(".connectedSortable");jQuery(f).find("p.nofields").hide("slow");jQuery.post(ajaxurl,{action:"xprofile_reorder_fields",cookie:encodeURIComponent(document.cookie),_wpnonce_reorder_fields:jQuery("input#_wpnonce_reorder_fields").val(),field_order:jQuery(f).sortable("serialize"),field_group_id:jQuery(f).attr("id")},function(i){})})},over:function(e,f){jQuery(this).addClass("drop-candidate")},out:function(e,f){jQuery(this).removeClass("drop-candidate")}})}});
    2  No newline at end of file
     1function add_option(e){var t=document.getElementById(e+"_more");var n=document.getElementById(e+"_option_number").value;var r=document.createElement("p");var i=document.createElement("input");var s=document.createElement("span");var o=document.createTextNode(" Ξ ");var u=document.createElement("input");var a=document.createElement("span");var f=document.createTextNode(" Default Value ");r.setAttribute("id",e+"_div"+n);r.setAttribute("class","sortable");i.setAttribute("type","text");i.setAttribute("name",e+"_option["+n+"]");i.setAttribute("id",e+"_option"+n);s.appendChild(o);if(e=="checkbox"||e=="multiselectbox"){u.setAttribute("type","checkbox");u.setAttribute("name","isDefault_"+e+"_option["+n+"]")}else{u.setAttribute("type","radio");u.setAttribute("name","isDefault_"+e+"_option")}u.setAttribute("value",n);a.appendChild(f);var l=document.createElement("a");var c=document.createTextNode("[x]");l.setAttribute("href","javascript:hide('"+e+"_div"+n+"')");l.setAttribute("class","delete");l.appendChild(c);r.appendChild(s);r.appendChild(i);r.appendChild(document.createTextNode(" "));r.appendChild(u);r.appendChild(a);r.appendChild(l);t.appendChild(r);enableSortableFieldOptions(e);document.getElementById(e+"_option"+n).focus();n++;document.getElementById(e+"_option_number").value=n}function show_options(e){document.getElementById("radio").style.display="none";document.getElementById("selectbox").style.display="none";document.getElementById("multiselectbox").style.display="none";document.getElementById("checkbox").style.display="none";if(e=="radio")document.getElementById("radio").style.display="";if(e=="selectbox")document.getElementById("selectbox").style.display="";if(e=="multiselectbox")document.getElementById("multiselectbox").style.display="";if(e=="checkbox")document.getElementById("checkbox").style.display=""}function hide(e){if(!document.getElementById(e))return false;document.getElementById(e).style.display="none";field_id=e.replace("div","option");document.getElementById(field_id).value=""}function enableSortableFieldOptions(e){if(jQuery("#"+e+" p.sortable").length>1){jQuery(".bp-options-box").sortable({items:"p.sortable",tolerance:"pointer",axis:"y",handle:"span"});jQuery(".sortable span").css("cursor","move")}}function destroySortableFieldOptions(){jQuery(".bp-options-box").sortable("destroy");jQuery(".sortable span").css("cursor","default")}var fixHelper=function(e,t){t.children().each(function(){jQuery(this).width(jQuery(this).width())});return t};jQuery(document).ready(function(){function n(t){e=jQuery("ul:first li",t).droppable({accept:".connectedSortable fieldset",hoverClass:"ui-state-hover",activeClass:"ui-state-acceptable",touch:"pointer",tolerance:"pointer",drop:function(n,r){var i=jQuery(this);var s=jQuery(i.find("a").attr("href")).find(".connectedSortable");jQuery(i).removeClass("drop-candidate");r.draggable.hide("slow",function(){t.tabs("option","active",e.index(i));jQuery(this).appendTo(s).show("slow").animate({opacity:"1"},500);s=jQuery(i.find("a").attr("href")).find(".connectedSortable");jQuery(s).find("p.nofields").hide("slow");jQuery.post(ajaxurl,{action:"xprofile_reorder_fields",cookie:encodeURIComponent(document.cookie),_wpnonce_reorder_fields:jQuery("input#_wpnonce_reorder_fields").val(),field_order:jQuery(s).sortable("serialize"),field_group_id:jQuery(s).attr("id")},function(e){})})},over:function(e,t){jQuery(this).addClass("drop-candidate")},out:function(e,t){jQuery(this).removeClass("drop-candidate")}})}jQuery("#bp-xprofile-add-field #title").focus();jQuery("a.ajax-option-delete").on("click",function(){var e=this.id.split("-");e=e[1];jQuery.post(ajaxurl,{action:"xprofile_delete_option",cookie:encodeURIComponent(document.cookie),_wpnonce:jQuery("input#_wpnonce").val(),option_id:e},function(e){})});jQuery('[id^="sort_order_"]').change(function(){if(jQuery(this).val()!="custom"){destroySortableFieldOptions()}else{enableSortableFieldOptions(jQuery("#fieldtype :selected").val())}});jQuery("ul#field-group-tabs").show();jQuery("ul#field-group-tabs").sortable({cursor:"move",axis:"x",opacity:.6,items:"li",tolerance:"pointer",update:function(){jQuery.post(ajaxurl,{action:"xprofile_reorder_groups",cookie:encodeURIComponent(document.cookie),_wpnonce_reorder_groups:jQuery("input#_wpnonce_reorder_groups").val(),group_order:jQuery(this).sortable("serialize")},function(e){})}}).disableSelection();jQuery("fieldset.field-group").sortable({cursor:"move",opacity:.3,items:"fieldset",tolerance:"pointer",update:function(){jQuery.post(ajaxurl,{action:"xprofile_reorder_fields",cookie:encodeURIComponent(document.cookie),_wpnonce_reorder_fields:jQuery("input#_wpnonce_reorder_fields").val(),field_order:jQuery(this).sortable("serialize"),field_group_id:jQuery(this).attr("id")},function(e){})}}).disableSelection().css("cursor","move");enableSortableFieldOptions(jQuery("#fieldtype :selected").val());var e;var t=jQuery("#tabs").tabs();n(t)})
     2 No newline at end of file
  • bp-xprofile/bp-xprofile-admin.php

     
    382382                <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>
    383383                <div class="field-wrapper">
    384384
    385                         <?php switch ( $field->type ) : case 'textbox' : ?>
     385                        <?php
     386                        $field_type = bp_xprofile_create_field_type( $field->type );
     387                        $field_type->admin_field_html();
    386388
    387                                 <input type="text" name="<?php bp_the_profile_field_input_name() ?>" id="<?php bp_the_profile_field_input_name() ?>" value="" />
     389                        do_action( 'xprofile_admin_field', $field, 1 );
     390                        ?>
    388391
    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 ); ?>
    446 
    447                         <?php endswitch; ?>
    448 
    449392                        <?php if ( $field->description ) : ?>
    450393
    451394                                <p class="description"><?php echo esc_attr( $field->description ); ?></p>
     
    467410<?php
    468411}
    469412
     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 */
     419function 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
    470464if ( ! class_exists( 'BP_XProfile_User_Admin' ) ) :
    471465/**
    472466 * Load xProfile Profile admin area.
     
    642636                                // Set the errors var
    643637                                $errors = false;
    644638
    645                                 // Now we've checked for required fields, lets save the values.
     639                                // Now we've checked for required fields, let's save the values.
    646640                                foreach ( (array) $posted_field_ids as $field_id ) {
    647641
    648642                                        // 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.
     
    702696                }
    703697
    704698                if ( bp_has_profile( $r ) ) :
    705 
    706699                        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() ); ?>" />
    707701
    708                                 <p class="description"><?php bp_the_profile_group_description(); ?></p>
     702                                <?php if ( bp_get_the_profile_group_description() ) : ?>
     703                                        <p class="description"><?php bp_the_profile_group_description(); ?></p>
     704                                <?php
     705                                endif;
    709706
    710                                 <table class="form-table">
    711                                         <tbody>
     707                                while ( bp_profile_fields() ) : bp_the_profile_field(); ?>
    712708
    713                                         <?php while ( bp_profile_fields() ) : bp_the_profile_field(); ?>
     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'] ) );
    714713
    715                                                 <tr>
     714                                                if ( bp_get_the_profile_field_description() ) : ?>
     715                                                        <p class="description"><?php bp_the_profile_field_description(); ?></p>
     716                                                <?php endif;
    716717
    717                                                         <?php if ( 'textbox' === 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                                                ?>
    718721
    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>
     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() );
    724725
     726                                                        if ( $can_change_visibility ) : ?>
     727                                                                 <a href="#" class="button visibility-toggle-link"><?php _e( 'Change', 'buddypress' ); ?></a>
    725728                                                        <?php endif; ?>
     729                                                </p>
    726730
    727                                                         <?php if ( 'textarea' === bp_get_the_profile_field_type() ) : ?>
     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;
    728740
    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>
     741                                                do_action( 'bp_custom_profile_edit_fields' ); ?>
     742                                        </div>
    734743
    735                                                         <?php endif; ?>
     744                                <?php
     745                                endwhile; // bp_profile_fields()
    736746
    737                                                         <?php if ( 'selectbox' === bp_get_the_profile_field_type() ) : ?>
    738 
    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>
    746 
    747                                                         <?php endif; ?>
    748 
    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">&nbsp;</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>
    861 
    862                                         <?php endwhile; ?>
    863                                         </tbody>
    864 
    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()
    868748                endif;
    869749        }
    870750
  • bp-xprofile/bp-xprofile-classes.php

     
    541541        public $default_visibility = 'public';
    542542        public $allow_custom_visibility = 'allowed';
    543543
     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
    544550        public $data;
    545551        public $message = null;
    546552        public $message_type = 'err';
    547553
    548554        public function __construct( $id = null, $user_id = null, $get_data = true ) {
    549                 if ( !empty( $id ) )
     555                if ( !empty( $id ) ) {
    550556                        $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                }
    551563        }
    552564
    553565        public function populate( $id, $user_id, $get_data ) {
     
    573585                        $this->order_by          = $field->order_by;
    574586                        $this->is_default_option = $field->is_default_option;
    575587
     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
    576592                        if ( $get_data && $user_id ) {
    577593                                $this->data          = $this->get_field_data( $user_id );
    578594                        }
     
    618634                $this->order_by    = apply_filters( 'xprofile_field_order_by_before_save',    $this->order_by,    $this->id );
    619635                $this->field_order = apply_filters( 'xprofile_field_field_order_before_save', $this->field_order, $this->id );
    620636                $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 );
    621638
    622639                do_action_ref_array( 'xprofile_field_before_save', array( $this ) );
    623640
     
    655672                         * Check to see if this is a field with child options.
    656673                         * We need to add the options to the db, if it is.
    657674                         */
    658                         if ( 'radio' == $this->type || 'selectbox' == $this->type || 'checkbox' == $this->type || 'multiselectbox' == $this->type ) {
     675                        if ( $this->type_obj->supports_options ) {
    659676
    660677                                if ( !empty( $this->id ) ) {
    661678                                        $parent_id = $this->id;
     
    663680                                        $parent_id = $wpdb->insert_id;
    664681                                }
    665682
    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'] : '';
     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 );
    669688
    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                                 }
    694 
    695689                                $counter = 1;
    696690                                if ( !empty( $options ) ) {
    697691                                        foreach ( (array) $options as $option_key => $option_value ) {
     
    718712
    719713                        do_action_ref_array( 'xprofile_field_after_save', array( $this ) );
    720714
     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
    721719                        return $field_id;
    722720                } else {
    723721                        return false;
     
    824822                return false;
    825823        }
    826824
    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         */
    832828        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>&nbsp;&Xi;&nbsp;</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&amp;mode=delete_option&amp;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>&nbsp;&Xi;&nbsp;</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                }
    918833        }
    919834
    920835        public function render_admin_form( $message = '' ) {
     
    1041956                                                                        <h3><label for="fieldtype"><?php _e( 'Field Type', 'buddypress'); ?></label></h3>
    1042957                                                                        <div class="inside">
    1043958                                                                                <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 ); ?>
    1055960                                                                                </select>
    1056961
    1057                                                                                 <?php do_action_ref_array( 'xprofile_field_additional_options', array( $this ) ); ?>
     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 );
    1058965
    1059                                                                                 <?php $this->render_admin_form_children(); ?>
    1060 
     966                                                                                $this->render_admin_form_children();
     967                                                                                ?>
    1061968                                                                        </div>
    1062969                                                                </div>
    1063970
     
    1086993                if ( '' == $_POST['title'] || '' == $_POST['required'] || '' == $_POST['fieldtype'] ) {
    1087994                        $message = __( 'Please make sure you fill out all required fields.', 'buddypress' );
    1088995                        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                        }
    11031005                }
     1006
     1007                return true;
    11041008        }
    11051009}
    11061010
    1107 
    11081011class BP_XProfile_ProfileData {
    11091012        public $id;
    11101013        public $user_id;
     
    15401443                return $data[$field_name];
    15411444        }
    15421445}
     1446
     1447/**
     1448 * Datebox xprofile field type.
     1449 *
     1450 * @since BuddyPress (2.0.0)
     1451 */
     1452class 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 */
     1696class 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 */
     1835class 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 */
     1970class BP_XProfile_Field_Type_Multiselectbox extends BP_XProfile_Field_Type {
     1971
     1972        /**
     1973         * Constructor for the multi-selectbox field type
     1974         *
     1975         * @since BuddyPress (2.0.0)
     1976         */
     1977        public function __construct() {
     1978                parent::__construct();
     1979
     1980                $this->category = _x( 'Multi Fields', 'xprofile field type category', 'buddypress' );
     1981                $this->name     = _x( 'Multi Select Box', 'xprofile field type', 'buddypress' );
     1982
     1983                $this->supports_multiple_defaults = true;
     1984                $this->accepts_null_value         = true;
     1985                $this->supports_options           = true;
     1986
     1987                $this->set_format( '/^.+$/', 'replace' );
     1988                do_action( 'bp_xprofile_field_type_multiselectbox', $this );
     1989        }
     1990
     1991        /**
     1992         * Output the edit field HTML for this field type.
     1993         *
     1994         * Must be used inside the {@link bp_profile_fields()} template loop.
     1995         *
     1996         * @param array $raw_properties Optional key/value array of {@link http://dev.w3.org/html5/markup/select.html permitted attributes} that you want to add.
     1997         * @since BuddyPress (2.0.0)
     1998         */
     1999        public function edit_field_html( array $raw_properties = array() ) {
     2000                $user_id = bp_displayed_user_id();
     2001
     2002                // user_id is a special optional parameter that we pass to {@link bp_the_profile_field_options()}.
     2003                if ( isset( $raw_properties['user_id'] ) ) {
     2004                        $user_id = (int) $raw_properties['user_id'];
     2005                        unset( $raw_properties['user_id'] );
     2006                }
     2007
     2008                $html = $this->get_edit_field_html_elements( array_merge(
     2009                        array( 'multiple' => 'multiple' ),
     2010                        $raw_properties
     2011                ) );
     2012        ?>
     2013                <label for="<?php bp_the_profile_field_input_name(); ?>"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php _e( '(required)', 'buddypress' ); ?><?php endif; ?></label>
     2014                <select <?php echo $html; ?>>
     2015                        <?php bp_the_profile_field_options( "user_id={$user_id}" ); ?>
     2016                </select>
     2017
     2018                <?php if ( ! bp_get_the_profile_field_is_required() ) : ?>
     2019                        <a class="clear-value" href="javascript:clear( '<?php echo esc_js( bp_get_the_profile_field_input_name() ); ?>' );"><?php esc_html_e( 'Clear', 'buddypress' ); ?></a>
     2020                <?php endif; ?>
     2021        <?php
     2022        }
     2023
     2024        /**
     2025         * Output the edit field options HTML for this field type.
     2026         *
     2027         * BuddyPress considers a field's "options" to be, for example, the items in a selectbox.
     2028         * These are stored separately in the database, and their templating is handled seperately.
     2029         *
     2030         * This templating is separate from {@link BP_XProfile_Field_Type::edit_field_html()} because
     2031         * it's also used in the wp-admin screens when creating new fields, and for backwards compatibility.
     2032         *
     2033         * Must be used inside the {@link bp_profile_fields()} template loop.
     2034         *
     2035         * @param array $args Optional. The arguments passed to {@link bp_the_profile_field_options()}.
     2036         * @since BuddyPress (2.0.0)
     2037         */
     2038        public function edit_field_options_html( array $args = array() ) {
     2039                $original_option_values = maybe_unserialize( BP_XProfile_ProfileData::get_value_byid( $this->field_obj->id, $args['user_id'] ) );
     2040
     2041                $options = $this->field_obj->get_children();
     2042                $html    = '';
     2043
     2044                if ( empty( $original_option_values ) && ! empty( $_POST['field_' . $this->field_obj->id] ) ) {
     2045                        $original_option_values = sanitize_text_field( $_POST['field_' . $this->field_obj->id] );
     2046                }
     2047
     2048                $option_values = (array) $original_option_values;
     2049                for ( $k = 0, $count = count( $options ); $k < $count; ++$k ) {
     2050                        $selected = '';
     2051
     2052                        // Check for updated posted values, but errors preventing them from being saved first time
     2053                        foreach( $option_values as $i => $option_value ) {
     2054                                if ( isset( $_POST['field_' . $this->field_obj->id] ) && $_POST['field_' . $this->field_obj->id][$i] != $option_value ) {
     2055                                        if ( ! empty( $_POST['field_' . $this->field_obj->id][$i] ) ) {
     2056                                                $option_values[] = sanitize_text_field( $_POST['field_' . $this->field_obj->id][$i] );
     2057                                        }
     2058                                }
     2059                        }
     2060
     2061                        // Run the allowed option name through the before_save filter, so we'll be sure to get a match
     2062                        $allowed_options = xprofile_sanitize_data_value_before_save( $options[$k]->name, false, false );
     2063
     2064                        // First, check to see whether the user-entered value matches
     2065                        if ( in_array( $allowed_options, $option_values ) ) {
     2066                                $selected = ' selected="selected"';
     2067                        }
     2068
     2069                        // Then, if the user has not provided a value, check for defaults
     2070                        if ( ! is_array( $original_option_values ) && empty( $option_values ) && ! empty( $options[$k]->is_default_option ) ) {
     2071                                $selected = ' selected="selected"';
     2072                        }
     2073
     2074                        $html .= apply_filters( 'bp_get_the_profile_field_options_multiselect', '<option' . $selected . ' value="' . esc_attr( stripslashes( $options[$k]->name ) ) . '">' . esc_html( stripslashes( $options[$k]->name ) ) . '</option>', $options[$k], $this->field_obj->id, $selected, $k );
     2075                }
     2076
     2077                echo $html;
     2078        }
     2079
     2080        /**
     2081         * Output HTML for this field type on the wp-admin Profile Fields screen.
     2082         *
     2083         * Must be used inside the {@link bp_profile_fields()} template loop.
     2084         *
     2085         * @param array $raw_properties Optional key/value array of permitted attributes that you want to add.
     2086         * @since BuddyPress (2.0.0)
     2087         */
     2088        public function admin_field_html( array $raw_properties = array() ) {
     2089                $html = $this->get_edit_field_html_elements( array_merge(
     2090                        array( 'multiple' => 'multiple' ),
     2091                        $raw_properties
     2092                ) );
     2093        ?>
     2094                <select <?php echo $html; ?>>
     2095                        <?php bp_the_profile_field_options(); ?>
     2096                </select>
     2097        <?php
     2098        }
     2099
     2100        /**
     2101         * Output HTML for this field type's children options on the wp-admin Profile Fields "Add Field" and "Edit Field" screens.
     2102         *
     2103         * Must be used inside the {@link bp_profile_fields()} template loop.
     2104         *
     2105         * @param BP_XProfile_Field $current_field The current profile field on the add/edit screen.
     2106         * @param string $control_type Optional. HTML input type used to render the current field's child options.
     2107         * @since BuddyPress (2.0.0)
     2108         */
     2109        public function admin_new_field_html( BP_XProfile_Field $current_field, $control_type = '' ) {
     2110                parent::admin_new_field_html( $current_field, 'checkbox' );
     2111        }
     2112}
     2113
     2114/**
     2115 * Selectbox xprofile field type.
     2116 *
     2117 * @since BuddyPress (2.0.0)
     2118 */
     2119class BP_XProfile_Field_Type_Selectbox extends BP_XProfile_Field_Type {
     2120
     2121        /**
     2122         * Constructor for the selectbox field type
     2123         *
     2124         * @since BuddyPress (2.0.0)
     2125         */
     2126        public function __construct() {
     2127                parent::__construct();
     2128
     2129                $this->category = _x( 'Multi Fields', 'xprofile field type category', 'buddypress' );
     2130                $this->name     = _x( 'Drop Down Select Box', 'xprofile field type', 'buddypress' );
     2131
     2132                $this->supports_options = true;
     2133
     2134                $this->set_format( '/^.+$/', 'replace' );
     2135                do_action( 'bp_xprofile_field_type_selectbox', $this );
     2136        }
     2137
     2138        /**
     2139         * Output the edit field HTML for this field type.
     2140         *
     2141         * Must be used inside the {@link bp_profile_fields()} template loop.
     2142         *
     2143         * @param array $raw_properties Optional key/value array of {@link http://dev.w3.org/html5/markup/select.html permitted attributes} that you want to add.
     2144         * @since BuddyPress (2.0.0)
     2145         */
     2146        public function edit_field_html( array $raw_properties = array() ) {
     2147                $user_id = bp_displayed_user_id();
     2148
     2149                // user_id is a special optional parameter that we pass to {@link bp_the_profile_field_options()}.
     2150                if ( isset( $raw_properties['user_id'] ) ) {
     2151                        $user_id = (int) $raw_properties['user_id'];
     2152                        unset( $raw_properties['user_id'] );
     2153                }
     2154
     2155                $html = $this->get_edit_field_html_elements( $raw_properties );
     2156        ?>
     2157                <label for="<?php bp_the_profile_field_input_name(); ?>"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php esc_html_e( '(required)', 'buddypress' ); ?><?php endif; ?></label>
     2158                <select <?php echo $html; ?>>
     2159                        <?php bp_the_profile_field_options( "user_id={$user_id}" ); ?>
     2160                </select>
     2161        <?php
     2162        }
     2163
     2164        /**
     2165         * Output the edit field options HTML for this field type.
     2166         *
     2167         * BuddyPress considers a field's "options" to be, for example, the items in a selectbox.
     2168         * These are stored separately in the database, and their templating is handled seperately.
     2169         *
     2170         * This templating is separate from {@link BP_XProfile_Field_Type::edit_field_html()} because
     2171         * it's also used in the wp-admin screens when creating new fields, and for backwards compatibility.
     2172         *
     2173         * Must be used inside the {@link bp_profile_fields()} template loop.
     2174         *
     2175         * @param array $args Optional. The arguments passed to {@link bp_the_profile_field_options()}.
     2176         * @since BuddyPress (2.0.0)
     2177         */
     2178        public function edit_field_options_html( array $args = array() ) {
     2179                $original_option_values = maybe_unserialize( BP_XProfile_ProfileData::get_value_byid( $this->field_obj->id, $args['user_id'] ) );
     2180
     2181                $options = $this->field_obj->get_children();
     2182                $html     = '<option value="">' . /* translators: no option picked in select box */ esc_html__( '----', 'buddypress' ) . '</option>';
     2183
     2184                if ( empty( $original_option_values ) && !empty( $_POST['field_' . $this->field_obj->id] ) ) {
     2185                        $original_option_values = sanitize_text_field(  $_POST['field_' . $this->field_obj->id] );
     2186                }
     2187
     2188                $option_values = (array) $original_option_values;
     2189                for ( $k = 0, $count = count( $options ); $k < $count; ++$k ) {
     2190                        $selected = '';
     2191
     2192                        // Check for updated posted values, but errors preventing them from being saved first time
     2193                        foreach( $option_values as $i => $option_value ) {
     2194                                if ( isset( $_POST['field_' . $this->field_obj->id] ) && $_POST['field_' . $this->field_obj->id] != $option_value ) {
     2195                                        if ( ! empty( $_POST['field_' . $this->field_obj->id] ) ) {
     2196                                                $option_values[$i] = sanitize_text_field( $_POST['field_' . $this->field_obj->id] );
     2197                                        }
     2198                                }
     2199                        }
     2200
     2201                        // Run the allowed option name through the before_save filter, so we'll be sure to get a match
     2202                        $allowed_options = xprofile_sanitize_data_value_before_save( $options[$k]->name, false, false );
     2203
     2204                        // First, check to see whether the user-entered value matches
     2205                        if ( in_array( $allowed_options, $option_values ) ) {
     2206                                $selected = ' selected="selected"';
     2207                        }
     2208
     2209                        // Then, if the user has not provided a value, check for defaults
     2210                        if ( ! is_array( $original_option_values ) && empty( $option_values ) && $options[$k]->is_default_option ) {
     2211                                $selected = ' selected="selected"';
     2212                        }
     2213
     2214                        $html .= apply_filters( 'bp_get_the_profile_field_options_select', '<option' . $selected . ' value="' . esc_attr( stripslashes( $options[$k]->name ) ) . '">' . esc_html( stripslashes( $options[$k]->name ) ) . '</option>', $options[$k], $this->field_obj->id, $selected, $k );
     2215                }
     2216
     2217                echo $html;
     2218        }
     2219
     2220        /**
     2221         * Output HTML for this field type on the wp-admin Profile Fields screen.
     2222         *
     2223         * Must be used inside the {@link bp_profile_fields()} template loop.
     2224         *
     2225         * @param array $raw_properties Optional key/value array of permitted attributes that you want to add.
     2226         * @since BuddyPress (2.0.0)
     2227         */
     2228        public function admin_field_html( array $raw_properties = array() ) {
     2229                $html = $this->get_edit_field_html_elements( $raw_properties );
     2230        ?>
     2231                <select <?php echo $html; ?>>
     2232                        <?php bp_the_profile_field_options(); ?>
     2233                </select>
     2234        <?php
     2235        }
     2236
     2237        /**
     2238         * Output HTML for this field type's children options on the wp-admin Profile Fields "Add Field" and "Edit Field" screens.
     2239         *
     2240         * Must be used inside the {@link bp_profile_fields()} template loop.
     2241         *
     2242         * @param BP_XProfile_Field $current_field The current profile field on the add/edit screen.
     2243         * @param string $control_type Optional. HTML input type used to render the current field's child options.
     2244         * @since BuddyPress (2.0.0)
     2245         */
     2246        public function admin_new_field_html( BP_XProfile_Field $current_field, $control_type = '' ) {
     2247                parent::admin_new_field_html( $current_field, 'radio' );
     2248        }
     2249}
     2250
     2251/**
     2252 * Textarea xprofile field type.
     2253 *
     2254 * @since BuddyPress (2.0.0)
     2255 */
     2256class BP_XProfile_Field_Type_Textarea extends BP_XProfile_Field_Type {
     2257
     2258        /**
     2259         * Constructor for the textarea field type
     2260         *
     2261         * @since BuddyPress (2.0.0)
     2262         */
     2263        public function __construct() {
     2264                parent::__construct();
     2265
     2266                $this->category = _x( 'Single Fields', 'xprofile field type category', 'buddypress' );
     2267                $this->name     = _x( 'Multi-line Text Area', 'xprofile field type', 'buddypress' );
     2268
     2269                $this->set_format( '/^.*$/m', 'replace' );
     2270                do_action( 'bp_xprofile_field_type_textarea', $this );
     2271        }
     2272
     2273        /**
     2274         * Output the edit field HTML for this field type.
     2275         *
     2276         * Must be used inside the {@link bp_profile_fields()} template loop.
     2277         *
     2278         * @param array $raw_properties Optional key/value array of {@link http://dev.w3.org/html5/markup/textarea.html permitted attributes} that you want to add.
     2279         * @since BuddyPress (2.0.0)
     2280         */
     2281        public function edit_field_html( array $raw_properties = array() ) {
     2282
     2283                // user_id is a special optional parameter that certain other fields types pass to {@link bp_the_profile_field_options()}.
     2284                if ( isset( $raw_properties['user_id'] ) ) {
     2285                        unset( $raw_properties['user_id'] );
     2286                }
     2287
     2288                $html = $this->get_edit_field_html_elements( array_merge(
     2289                        array(
     2290                                'cols' => 40,
     2291                                'rows' => 5,
     2292                        ),
     2293                        $raw_properties
     2294                ) );
     2295        ?>
     2296                <label for="<?php bp_the_profile_field_input_name(); ?>"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php esc_html_e( '(required)', 'buddypress' ); ?><?php endif; ?></label>
     2297                <textarea <?php echo $html; ?>><?php bp_the_profile_field_edit_value(); ?></textarea>
     2298        <?php
     2299        }
     2300
     2301        /**
     2302         * Output HTML for this field type on the wp-admin Profile Fields screen.
     2303         *
     2304         * Must be used inside the {@link bp_profile_fields()} template loop.
     2305         *
     2306         * @param array $raw_properties Optional key/value array of permitted attributes that you want to add.
     2307         * @since BuddyPress (2.0.0)
     2308         */
     2309        public function admin_field_html( array $raw_properties = array() ) {
     2310                $html = $this->get_edit_field_html_elements( array_merge(
     2311                        array(
     2312                                'cols' => 40,
     2313                                'rows' => 5,
     2314                        ),
     2315                        $raw_properties
     2316                ) );
     2317        ?>
     2318                <textarea <?php echo $html; ?>></textarea>
     2319        <?php
     2320        }
     2321
     2322        /**
     2323         * This method usually outputs HTML for this field type's children options on the wp-admin Profile Fields
     2324         * "Add Field" and "Edit Field" screens, but for this field type, we don't want it, so it's stubbed out.
     2325         *
     2326         * @param BP_XProfile_Field $current_field The current profile field on the add/edit screen.
     2327         * @param string $control_type Optional. HTML input type used to render the current field's child options.
     2328         * @since BuddyPress (2.0.0)
     2329         */
     2330        public function admin_new_field_html( BP_XProfile_Field $current_field, $control_type = '' ) {}
     2331}
     2332
     2333/**
     2334 * Textbox xprofile field type.
     2335 *
     2336 * @since BuddyPress (2.0.0)
     2337 */
     2338class BP_XProfile_Field_Type_Textbox extends BP_XProfile_Field_Type {
     2339
     2340        /**
     2341         * Constructor for the textbox field type
     2342         *
     2343         * @since BuddyPress (2.0.0)
     2344         */
     2345        public function __construct() {
     2346                parent::__construct();
     2347
     2348                $this->category = _x( 'Single Fields', 'xprofile field type category', 'buddypress' );
     2349                $this->name     = _x( 'Text Box', 'xprofile field type', 'buddypress' );
     2350
     2351                $this->set_format( '/^.*$/', 'replace' );
     2352                do_action( 'bp_xprofile_field_type_textbox', $this );
     2353        }
     2354
     2355        /**
     2356         * Output the edit field HTML for this field type.
     2357         *
     2358         * Must be used inside the {@link bp_profile_fields()} template loop.
     2359         *
     2360         * @param array $raw_properties Optional key/value array of {@link http://dev.w3.org/html5/markup/input.text.html permitted attributes} that you want to add.
     2361         * @since BuddyPress (2.0.0)
     2362         */
     2363        public function edit_field_html( array $raw_properties = array() ) {
     2364
     2365                // user_id is a special optional parameter that certain other fields types pass to {@link bp_the_profile_field_options()}.
     2366                if ( isset( $raw_properties['user_id'] ) ) {
     2367                        unset( $raw_properties['user_id'] );
     2368                }
     2369
     2370                $html = $this->get_edit_field_html_elements( array_merge(
     2371                        array(
     2372                                'type'  => 'text',
     2373                                'value' => bp_get_the_profile_field_edit_value(),
     2374                        ),
     2375                        $raw_properties
     2376                ) );
     2377        ?>
     2378                <label for="<?php bp_the_profile_field_input_name(); ?>"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php esc_html_e( '(required)', 'buddypress' ); ?><?php endif; ?></label>
     2379                <input <?php echo $html; ?>>
     2380        <?php
     2381        }
     2382
     2383        /**
     2384         * Output HTML for this field type on the wp-admin Profile Fields screen.
     2385         *
     2386         * Must be used inside the {@link bp_profile_fields()} template loop.
     2387         *
     2388         * @param array $raw_properties Optional key/value array of permitted attributes that you want to add.
     2389         * @since BuddyPress (2.0.0)
     2390         */
     2391        public function admin_field_html( array $raw_properties = array() ) {
     2392                $html = $this->get_edit_field_html_elements( array_merge(
     2393                        array( 'type' => 'text' ),
     2394                        $raw_properties
     2395                ) );
     2396        ?>
     2397                <input <?php echo $html; ?>>
     2398        <?php
     2399        }
     2400
     2401        /**
     2402         * This method usually outputs HTML for this field type's children options on the wp-admin Profile Fields
     2403         * "Add Field" and "Edit Field" screens, but for this field type, we don't want it, so it's stubbed out.
     2404         *
     2405         * @param BP_XProfile_Field $current_field The current profile field on the add/edit screen.
     2406         * @param string $control_type Optional. HTML input type used to render the current field's child options.
     2407         * @since BuddyPress (2.0.0)
     2408         */
     2409        public function admin_new_field_html( BP_XProfile_Field $current_field, $control_type = '' ) {}
     2410}
     2411
     2412/**
     2413 * Number xprofile field type.
     2414 *
     2415 * @since BuddyPress (2.0.0)
     2416 */
     2417class BP_XProfile_Field_Type_Number extends BP_XProfile_Field_Type {
     2418
     2419        /**
     2420         * Constructor for the number field type
     2421         *
     2422         * @since BuddyPress (2.0.0)
     2423         */
     2424        public function __construct() {
     2425                parent::__construct();
     2426
     2427                $this->category = _x( 'Single Fields', 'xprofile field type category', 'buddypress' );
     2428                $this->name     = _x( 'Number', 'xprofile field type', 'buddypress' );
     2429
     2430                $this->set_format( '/^\d+$/', 'replace' );
     2431                do_action( 'bp_xprofile_field_type_number', $this );
     2432        }
     2433
     2434        /**
     2435         * Output the edit field HTML for this field type.
     2436         *
     2437         * Must be used inside the {@link bp_profile_fields()} template loop.
     2438         *
     2439         * @param array $raw_properties Optional key/value array of {@link http://dev.w3.org/html5/markup/input.number.html permitted attributes} that you want to add.
     2440         * @since BuddyPress (2.0.0)
     2441         */
     2442        public function edit_field_html( array $raw_properties = array() ) {
     2443
     2444                // user_id is a special optional parameter that certain other fields types pass to {@link bp_the_profile_field_options()}.
     2445                if ( isset( $raw_properties['user_id'] ) ) {
     2446                        unset( $raw_properties['user_id'] );
     2447                }
     2448
     2449                $html = $this->get_edit_field_html_elements( array_merge(
     2450                        array(
     2451                                'type'  => 'number',
     2452                                'value' => bp_get_the_profile_field_edit_value(),
     2453                        ),
     2454                        $raw_properties
     2455                ) );
     2456        ?>
     2457                <label for="<?php bp_the_profile_field_input_name(); ?>"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php esc_html_e( '(required)', 'buddypress' ); ?><?php endif; ?></label>
     2458                <input <?php echo $html; ?>>
     2459        <?php
     2460        }
     2461
     2462        /**
     2463         * Output HTML for this field type on the wp-admin Profile Fields screen.
     2464         *
     2465         * Must be used inside the {@link bp_profile_fields()} template loop.
     2466         *
     2467         * @param array $raw_properties Optional key/value array of permitted attributes that you want to add.
     2468         * @since BuddyPress (2.0.0)
     2469         */
     2470        public function admin_field_html( array $raw_properties = array() ) {
     2471                $html = $this->get_edit_field_html_elements( array_merge(
     2472                        array( 'type' => 'number' ),
     2473                        $raw_properties
     2474                ) );
     2475        ?>
     2476                <input <?php echo $html; ?>>
     2477        <?php
     2478        }
     2479
     2480        /**
     2481         * This method usually outputs HTML for this field type's children options on the wp-admin Profile Fields
     2482         * "Add Field" and "Edit Field" screens, but for this field type, we don't want it, so it's stubbed out.
     2483         *
     2484         * @param BP_XProfile_Field $current_field The current profile field on the add/edit screen.
     2485         * @param string $control_type Optional. HTML input type used to render the current field's child options.
     2486         * @since BuddyPress (2.0.0)
     2487         */
     2488        public function admin_new_field_html( BP_XProfile_Field $current_field, $control_type = '' ) {}
     2489}
     2490
     2491/**
     2492 * Represents a type of XProfile field and holds meta information about the type of value that it accepts.
     2493 *
     2494 * @since BuddyPress (2.0.0)
     2495 */
     2496abstract class BP_XProfile_Field_Type {
     2497
     2498        /**
     2499         * @since BuddyPress (2.0.0)
     2500         * @var array Field type validation regexes
     2501         */
     2502        protected $validation_regex = array();
     2503
     2504        /**
     2505         * @since BuddyPress (2.0.0)
     2506         * @var array Field type whitelisted values
     2507         */
     2508        protected $validation_whitelist = array();
     2509
     2510        /**
     2511         * @since BuddyPress (2.0.0)
     2512         * @var string The name of this field type
     2513         */
     2514        public $name = '';
     2515
     2516        /**
     2517         * The name of the category that this field type should be grouped with. Used on the [Users > Profile Fields] screen in wp-admin.
     2518         *
     2519         * @since BuddyPress (2.0.0)
     2520         * @var string
     2521         */
     2522        public $category = '';
     2523
     2524        /**
     2525         * @since BuddyPress (2.0.0)
     2526         * @var bool If this is set, allow BP to store null/empty values for this field type.
     2527         */
     2528        public $accepts_null_value = false;
     2529
     2530        /**
     2531         * If this is set, BP will set this field type's validation whitelist from the field's options (e.g checkbox, selectbox).
     2532         *
     2533         * @since BuddyPress (2.0.0)
     2534         * @var bool Does this field support options? e.g. selectbox, radio buttons, etc.
     2535         */
     2536        public $supports_options = false;
     2537
     2538        /**
     2539         * @since BuddyPress (2.0.0)
     2540         * @var bool Does this field type support multiple options being set as default values? e.g. multiselectbox, checkbox.
     2541         */
     2542        public $supports_multiple_defaults = false;
     2543
     2544        /**
     2545         * @since BuddyPress (2.0.0)
     2546         * @var BP_XProfile_Field If this object is created by instantiating a {@link BP_XProfile_Field}, this is a reference back to that object.
     2547         */
     2548        public $field_obj = null;
     2549
     2550        /**
     2551         * Constructor
     2552         *
     2553         * @since BuddyPress (2.0.0)
     2554         */
     2555        public function __construct() {
     2556                do_action( 'bp_xprofile_field_type', $this );
     2557        }
     2558
     2559        /**
     2560         * Set a regex that profile data will be asserted against.
     2561         *
     2562         * You can call this method multiple times to set multiple formats. When validation is performed,
     2563         * it's successful as long as the new value matches any one of the registered formats.
     2564         *
     2565         * @param string $format Regex string
     2566         * @param string $replace_format Optional; if 'replace', replaces the format instead of adding to it. Defaults to 'add'.
     2567         * @return BP_XProfile_Field_Type
     2568         * @since BuddyPress (2.0.0)
     2569         */
     2570        public function set_format( $format, $replace_format = 'add' ) {
     2571
     2572                $format = apply_filters( 'bp_xprofile_field_type_set_format', $format, $replace_format, $this );
     2573
     2574                if ( 'add' === $replace_format ) {
     2575                        $this->validation_regex[] = $format;
     2576                } elseif ( 'replace' === $replace_format ) {
     2577                        $this->validation_regex = array( $format );
     2578                }
     2579
     2580                return $this;
     2581        }
     2582
     2583        /**
     2584         * Add a value to this type's whitelist that that profile data will be asserted against.
     2585         *
     2586         * You can call this method multiple times to set multiple formats. When validation is performed,
     2587         * it's successful as long as the new value matches any one of the registered formats.
     2588         *
     2589         * @param string|array $values
     2590         * @return BP_XProfile_Field_Type
     2591         * @since BuddyPress (2.0.0)
     2592         */
     2593        public function set_whitelist_values( $values ) {
     2594                foreach ( (array) $values as $value ) {
     2595                        $this->validation_whitelist[] = apply_filters( 'bp_xprofile_field_type_set_whitelist_values', $value, $values, $this );
     2596                }
     2597
     2598                return $this;
     2599        }
     2600
     2601        /**
     2602         * Check the given string against the registered formats for this field type.
     2603         *
     2604         * This method doesn't support chaining.
     2605         *
     2606         * @param string|array $values Value to check against the registered formats
     2607         * @return bool True if the value validates
     2608         * @since BuddyPress (2.0.0)
     2609         */
     2610        public function is_valid( $values ) {
     2611                $validated = false;
     2612
     2613                // Some types of field (e.g. multi-selectbox) may have multiple values to check
     2614                foreach ( (array) $values as $value ) {
     2615
     2616                        // Validate the $value against the type's accepted format(s).
     2617                        foreach ( $this->validation_regex as $format ) {
     2618                                if ( 1 === preg_match( $format, $value ) ) {
     2619                                        $validated = true;
     2620                                        continue;
     2621
     2622                                } else {
     2623                                        $validated = false;
     2624                                }
     2625                        }
     2626                }
     2627
     2628                // Handle field types with accepts_null_value set if $values is an empty array
     2629                if ( ! $validated && is_array( $values ) && empty( $values ) && $this->accepts_null_value ) {
     2630                        $validated = true;
     2631                }
     2632
     2633                // If there's a whitelist set, also check the $value.
     2634                if ( $validated && ! empty( $values ) && ! empty( $this->validation_whitelist ) ) {
     2635
     2636                        foreach ( (array) $values as $value ) {
     2637                                $validated = in_array( $value, $this->validation_whitelist, true );
     2638                        }
     2639                }
     2640
     2641                return (bool) apply_filters( 'bp_xprofile_field_type_is_valid', $validated, $values, $this );
     2642        }
     2643
     2644        /**
     2645         * Output the edit field HTML for this field type.
     2646         *
     2647         * Must be used inside the {@link bp_profile_fields()} template loop.
     2648         *
     2649         * @param array $raw_properties Optional key/value array of permitted attributes that you want to add.
     2650         * @since BuddyPress (2.0.0)
     2651         */
     2652        abstract public function edit_field_html( array $raw_properties = array() );
     2653
     2654        /**
     2655         * Output the edit field options HTML for this field type.
     2656         *
     2657         * BuddyPress considers a field's "options" to be, for example, the items in a selectbox.
     2658         * These are stored separately in the database, and their templating is handled separately.
     2659         * Populate this method in a child class if it's required. Otherwise, you can leave it out.
     2660         *
     2661         * This templating is separate from {@link BP_XProfile_Field_Type::edit_field_html()} because
     2662         * it's also used in the wp-admin screens when creating new fields, and for backwards compatibility.
     2663         *
     2664         * Must be used inside the {@link bp_profile_fields()} template loop.
     2665         *
     2666         * @param array $args Optional. The arguments passed to {@link bp_the_profile_field_options()}.
     2667         * @since BuddyPress (2.0.0)
     2668         */
     2669        public function edit_field_options_html( array $args = array() ) {}
     2670
     2671        /**
     2672         * Output HTML for this field type on the wp-admin Profile Fields screen.
     2673         *
     2674         * Must be used inside the {@link bp_profile_fields()} template loop.
     2675         *
     2676         * @param array $raw_properties Optional key/value array of permitted attributes that you want to add.
     2677         * @since BuddyPress (2.0.0)
     2678         */
     2679        abstract public function admin_field_html( array $raw_properties = array() );
     2680
     2681        /**
     2682         * Output HTML for this field type's children options on the wp-admin Profile Fields "Add Field" and "Edit Field" screens.
     2683         *
     2684         * You don't need to implement this method for all field types. It's used in core by the
     2685         * selectbox, multi selectbox, checkbox, and radio button fields, to allow the admin to
     2686         * enter the child option values (e.g. the choices in a select box).
     2687         *
     2688         * Must be used inside the {@link bp_profile_fields()} template loop.
     2689         *
     2690         * @param BP_XProfile_Field $current_field The current profile field on the add/edit screen.
     2691         * @param string $control_type Optional. HTML input type used to render the current field's child options.
     2692         * @since BuddyPress (2.0.0)
     2693         */
     2694        public function admin_new_field_html( BP_XProfile_Field $current_field, $control_type = '' ) {
     2695                $type = array_search( get_class( $this ), bp_xprofile_get_field_types() );
     2696                if ( false === $type ) {
     2697                        return;
     2698                }
     2699
     2700                $class            = $current_field->type != $type ? 'display: none;' : '';
     2701                $current_type_obj = bp_xprofile_create_field_type( $type );
     2702                ?>
     2703
     2704                <div id="<?php echo esc_attr( $type ); ?>" class="postbox bp-options-box" style="<?php echo esc_attr( $class ); ?> margin-top: 15px;">
     2705                        <h3><?php esc_html_e( 'Please enter options for this Field:', 'buddypress' ); ?></h3>
     2706                        <div class="inside">
     2707                                <p>
     2708                                        <label for="sort_order_<?php echo esc_attr( $type ); ?>"><?php esc_html_e( 'Sort Order:', 'buddypress' ); ?></label>
     2709                                        <select name="sort_order_<?php echo esc_attr( $type ); ?>" id="sort_order_<?php echo esc_attr( $type ); ?>" >
     2710                                                <option value="custom" <?php selected( 'custom', $current_field->order_by ); ?>><?php esc_html_e( 'Custom',     'buddypress' ); ?></option>
     2711                                                <option value="asc"    <?php selected( 'asc',    $current_field->order_by ); ?>><?php esc_html_e( 'Ascending',  'buddypress' ); ?></option>
     2712                                                <option value="desc"   <?php selected( 'desc',   $current_field->order_by ); ?>><?php esc_html_e( 'Descending', 'buddypress' ); ?></option>
     2713                                        </select>
     2714                                </p>
     2715
     2716                                <?php
     2717                                $options = $current_field->get_children( true );
     2718
     2719                                // If no children options exists for this field, check in $_POST for a submitted form (e.g. on the "new field" screen).
     2720                                if ( ! $options ) {
     2721
     2722                                        $options = array();
     2723                                        $i       = 1;
     2724
     2725                                        while ( isset( $_POST[$type . '_option'][$i] ) ) {
     2726
     2727                                                // Multiselectbox and checkboxes support MULTIPLE default options; all other core types support only ONE.
     2728                                                if ( $current_type_obj->supports_options && ! $current_type_obj->supports_multiple_defaults && isset( $_POST["isDefault_{$type}_option"][$i] ) && (int) $_POST["isDefault_{$type}_option"] === $i ) {
     2729                                                        $is_default_option = true;
     2730                                                } elseif ( isset( $_POST["isDefault_{$type}_option"][$i] ) ) {
     2731                                                        $is_default_option = (bool) $_POST["isDefault_{$type}_option"][$i];
     2732                                                } else {
     2733                                                        $is_default_option = false;
     2734                                                }
     2735
     2736                                                // Grab the values from $_POST to use as the form's options
     2737                                                $options[] = (object) array(
     2738                                                        'id'                => -1,
     2739                                                        'is_default_option' => $is_default_option,
     2740                                                        'name'              => sanitize_text_field( stripslashes( $_POST[$type . '_option'][$i] ) ),
     2741                                                );
     2742
     2743                                                ++$i;
     2744                                        }
     2745
     2746                                        // If there are still no children options set, this must be the "new field" screen, so add one new/empty option.
     2747                                        if ( ! $options ) {
     2748                                                $options[] = (object) array(
     2749                                                        'id'                => -1,
     2750                                                        'is_default_option' => false,
     2751                                                        'name'              => '',
     2752                                                );
     2753                                        }
     2754                                }
     2755
     2756                                // Render the markup for the children options
     2757                                if ( ! empty( $options ) ) {
     2758                                        $default_name = '';
     2759
     2760                                        for ( $i = 0, $count = count( $options ); $i < $count; ++$i ) :
     2761                                                $j = $i + 1;
     2762
     2763                                                // Multiselectbox and checkboxes support MULTIPLE default options; all other core types support only ONE.
     2764                                                if ( $current_type_obj->supports_options && $current_type_obj->supports_multiple_defaults ) {
     2765                                                        $default_name = '[' . $j . ']';
     2766                                                }
     2767                                                ?>
     2768
     2769                                                <p class="sortable">
     2770                                                        <span>&nbsp;&Xi;&nbsp;</span>
     2771                                                        <input type="text" name="<?php echo esc_attr( "{$type}_option[{$j}]" ); ?>" id="<?php echo esc_attr( "{$type}_option{$j}" ); ?>" value="<?php echo esc_attr( $options[$i]->name ); ?>" />
     2772                                                        <input type="<?php echo esc_attr( $control_type ); ?>" name="<?php echo esc_attr( "isDefault_{$type}_option{$default_name}" ); ?>" <?php checked( $options[$i]->is_default_option, true ); ?> value="<?php echo esc_attr( $j ); ?>" />
     2773                                                        <span><?php _e( 'Default Value', 'buddypress' ); ?></span>
     2774                                                </p>
     2775                                        <?php endfor; ?>
     2776
     2777                                        <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 ); ?>" />
     2778                                <?php } ?>
     2779
     2780                                <div id="<?php echo esc_attr( "{$type}_more" ); ?>"></div>
     2781                                <p><a href="javascript:add_option('<?php echo esc_js( $type ); ?>')"><?php esc_html_e( 'Add Another Option', 'buddypress' ); ?></a></p>
     2782                        </div>
     2783                </div>
     2784
     2785                <?php
     2786        }
     2787
     2788
     2789        /**
     2790         * Internal protected/private helper methods past this point.
     2791         */
     2792
     2793        /**
     2794         * Get a sanitised and escaped string of the edit field's HTML elements and attributes.
     2795         *
     2796         * Must be used inside the {@link bp_profile_fields()} template loop.
     2797         * This method was intended to be static but couldn't be because php.net/lsb/ requires PHP >= 5.3.
     2798         *
     2799         * @param array $properties Optional key/value array of attributes for this edit field.
     2800         * @return string
     2801         * @since BuddyPress (2.0.0)
     2802         */
     2803        protected function get_edit_field_html_elements( array $properties = array() ) {
     2804
     2805                $properties = array_merge( array(
     2806                        'id'   => bp_get_the_profile_field_input_name(),
     2807                        'name' => bp_get_the_profile_field_input_name(),
     2808                ), $properties );
     2809
     2810                if ( bp_get_the_profile_field_is_required() ) {
     2811                        $properties['aria-required'] = 'true';
     2812                }
     2813
     2814                $html       = '';
     2815                $properties = (array) apply_filters( 'bp_xprofile_field_edit_html_elements', $properties, get_class( $this ) );
     2816
     2817                foreach ( $properties as $name => $value ) {
     2818                        $html .= sprintf( '%s="%s" ', sanitize_key( $name ), esc_attr( $value ) );
     2819                }
     2820
     2821                return $html;
     2822        }
     2823}
  • bp-xprofile/bp-xprofile-functions.php

     
    6060
    6161/*** Field Management *********************************************************/
    6262
     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 */
     69function 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 */
     92function 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
    63108function xprofile_insert_field( $args = '' ) {
    64109        global $bp;
    65110
     
    214259        if ( $is_required && ( empty( $value ) || !is_array( $value ) && !strlen( trim( $value ) ) ) )
    215260                return false;
    216261
    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 ) );
    218264
    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 ) {
    222267                xprofile_delete_field_data( $field_id, $user_id );
    223268                return true;
    224269        }
    225270
    226         $possible_values = array();
     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        }
    227275
    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                         }
    241 
    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;
    249279        }
    250280
    251281        $field           = new BP_XProfile_ProfileData();
  • bp-xprofile/bp-xprofile-loader.php

     
    9898                }
    9999
    100100                // 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() ) );
    110102
    111103                // Register the visibility levels. See bp_xprofile_get_visibility_levels() to filter
    112104                $this->visibility_levels = array(
  • bp-xprofile/bp-xprofile-template.php

     
    221221                if ( $profile_template->current_field % 2 == 1 )
    222222                        $css_classes[] = 'alt';
    223223
     224                $css_classes[] = 'field_type_' . sanitize_title( $profile_template->field->type );
    224225                $css_classes = apply_filters_ref_array( 'bp_field_css_classes', array( &$css_classes ) );
    225226
    226227                return apply_filters( 'bp_get_field_css_class', ' class="' . implode( ' ', $css_classes ) . '"' );
     
    423424 *
    424425 * @param array $args Specify type for datebox. Allowed 'day', 'month', 'year'.
    425426 */
    426 function bp_the_profile_field_options( $args = '' ) {
     427function bp_the_profile_field_options( $args = array() ) {
    427428        echo bp_get_the_profile_field_options( $args );
    428429}
    429430        /**
    430431         * bp_get_the_profile_field_options()
    431432         *
    432          * Retrieves field options HTML for field types of 'selectbox', 'multiselectbox',
    433          * 'radio', 'checkbox', and 'datebox'.
     433         * Retrieves field options HTML for field types of 'selectbox', 'multiselectbox', 'radio', 'checkbox', and 'datebox'.
    434434         *
    435435         * @package BuddyPress Xprofile
    436436         * @since BuddyPress (1.1)
     
    446446         *           used when rendering options. Default: displayed user.
    447447         * }
    448448         */
    449         function bp_get_the_profile_field_options( $args = '' ) {
     449        function bp_get_the_profile_field_options( $args = array() ) {
    450450                global $field;
    451451
    452                 $defaults = array(
     452                $args = bp_parse_args( $args, array(
    453453                        'type'    => false,
    454454                        'user_id' => bp_displayed_user_id(),
    455                 );
     455                ), 'profile_field_options_args' );
    456456
    457                 $r = wp_parse_args( $args, $defaults );
    458                 extract( $r, EXTR_SKIP );
    459 
    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' ) ) {
     457                /**
     458                 * In some cases, the $field global is not an instantiation of the BP_XProfile_Field class.
     459                 * However, we have to make sure that all data originally in $field gets merged back in, after reinstantiation.
     460                 */
     461                if ( ! method_exists( $field, 'get_children' ) ) {
    464462                        $field_obj = new BP_XProfile_Field( $field->id );
    465463
    466                         foreach( $field as $field_prop => $field_prop_value ) {
    467                                 if ( !isset( $field_obj->{$field_prop} ) ) {
     464                        foreach ( $field as $field_prop => $field_prop_value ) {
     465                                if ( ! isset( $field_obj->{$field_prop} ) )
    468466                                        $field_obj->{$field_prop} = $field_prop_value;
    469                                 }
    470467                        }
    471468
    472469                        $field = $field_obj;
    473470                }
    474471
    475                 $options = $field->get_children();
     472                ob_start();
     473                $field->type_obj->edit_field_options_html( $args );
     474                $html = ob_get_contents();
     475                ob_end_clean();
    476476
    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                 }
    720 
    721477                return $html;
    722478        }
    723479
     
    1014770
    1015771                // Output the dropdown list
    1016772                return apply_filters( 'bp_xprofile_settings_visibility_select', ob_get_clean() );
    1017         }
    1018  No newline at end of file
     773        }
  • tests/testcases/xprofile/class-bp-xprofile-field-type.php

     
     1<?php
     2/**
     3 * @group xprofile
     4 * @group BP_XProfile_Field_Type
     5 */
     6class 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}