Ticket #5220: 5220.03.diff
File 5220.03.diff, 130.8 KB (added by , 11 years ago) |
---|
-
bp-members/admin/css/admin.css
15 15 width:100%; 16 16 } 17 17 18 div#community-profile-page h2:first-of-type {19 margin-bottom:1em;20 }21 22 div#community-profile-page h2.profile-section {23 border-bottom:dotted 1px #ccc;24 }25 26 18 div#community-profile-page ul#profile-nav { 27 19 border-bottom:solid 1px #ccc; 28 20 width:100%; … … 104 96 color:red; 105 97 } 106 98 107 div#community-profile-page .form-table td.admin-field-visibility-td{108 padding:5px 5px 15px 5px;99 .alt { 100 background: none; 109 101 } 110 111 div#community-profile-page .form-table tr.admin-field-visibility-tr { 112 border-bottom:dotted 1px #ccc; 102 .bp-profile-field { 103 border-bottom: dotted 1px #ccc; 104 font-size: 14px; 105 margin: 15px 0; 113 106 } 114 115 div#community-profile-page .form-table tr.admin-field-visibility-tr:last-child{ 116 border:none; 107 .bp-profile-field:last-child { 108 border-bottom: 0; 117 109 } 118 119 div#community-profile-page .field-visibility-settings legend, 120 div#community-profile-page .field-visibility-settings-notoggle { 110 .bp-profile-field p { 121 111 font-size: 14px; 122 font-style: italic;123 color:#666;124 112 } 125 126 div#community-profile-page .field-visibility-settings ul { 127 margin:0; 128 font-size: 13px; 113 .bp-profile-field .datebox > label, 114 .bp-profile-field .radio > label, 115 .bp-profile-field > label { /* label takes on left side 200px */ 116 display: inline-block; 117 font-weight: 600; 118 text-align: left; 119 vertical-align: middle; 120 width: 200px; 129 121 } 130 122 131 div#community-profile-page .field-visibility-settings ul li { 132 display:inline-block; 133 margin-right:1em; 123 .field_type_textarea > label, 124 .field_type_multiselectbox > label, 125 .field_type_radio .radio > label, 126 .field_type_checkbox .checkbox > label { /* these fields are usually pretty tall, so align the label for better consistency */ 127 vertical-align: top; 134 128 } 135 136 div#community-profile-page .form-table td.admin-field-radio label, 137 div#community-profile-page .form-table td.admin-field-checkbox label { 138 display:block; 129 .bp-profile-field .description { /* description also sits in the right side column */ 130 margin: 10px 0 10px 200px; 131 text-align: left; 139 132 } 140 141 .field-visibility-settings { 133 .clear-value { /* 'clear value' option also sits in the right side column */ 134 display: block; 135 font-size: 12px; 136 margin-left: 200px; 137 } 138 .field_type_checkbox .checkbox > label + label { /* force checkboxes to new lines, in the right side column */ 139 display: block; 140 margin-left: 200px; 141 width: auto; 142 } 143 .field_type_radio .radio div:not(.field-visibility-settings) label { /* force radio buttons to new lines */ 144 display: block; 145 } 146 .field_type_radio .radio div:not(.field-visibility-settings) { /* make the radio buttons sit in the right side column */ 147 display: inline-block; 148 } 149 .field-visibility-settings-notoggle, 150 .field-visibility-settings-toggle { /* visibility settings go in the left column */ 151 margin: 10px 0 10px 200px; 152 text-align: left; 153 } 154 .field-visibility-settings { /* visibility settings go in the left column */ 142 155 display: none; 143 } 144 No newline at end of file 156 margin-left: 200px; 157 } 158 .field-visibility-settings .button { /* visibility setting close button */ 159 margin-bottom: 15px; 160 } 161 #normal-sortables .field-visibility-settings legend { /* id required for css selector weight */ 162 font-size: 16px; 163 margin-bottom: 10px; 164 } -
bp-templates/bp-legacy/buddypress/members/register.php
68 68 69 69 <div class="editfield"> 70 70 71 <?php if ( 'textbox' == bp_get_the_profile_field_type() ) : ?> 71 <?php 72 $field_type = bp_xprofile_create_field_type( bp_get_the_profile_field_type() ); 73 $field_type->edit_field_html(); 72 74 73 <label for="<?php bp_the_profile_field_input_name(); ?>"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php _e( '(required)', 'buddypress' ); ?><?php endif; ?></label> 74 <?php do_action( bp_get_the_profile_field_errors_action() ); ?> 75 <input type="text" name="<?php bp_the_profile_field_input_name(); ?>" id="<?php bp_the_profile_field_input_name(); ?>" value="<?php bp_the_profile_field_edit_value(); ?>" /> 75 do_action( 'bp_custom_profile_edit_fields_pre_visibility' ); 76 76 77 <?php endif; ?> 78 79 <?php if ( 'textarea' == bp_get_the_profile_field_type() ) : ?> 80 81 <label for="<?php bp_the_profile_field_input_name(); ?>"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php _e( '(required)', 'buddypress' ); ?><?php endif; ?></label> 82 <?php do_action( bp_get_the_profile_field_errors_action() ); ?> 83 <textarea rows="5" cols="40" name="<?php bp_the_profile_field_input_name(); ?>" id="<?php bp_the_profile_field_input_name(); ?>"><?php bp_the_profile_field_edit_value(); ?></textarea> 84 85 <?php endif; ?> 86 87 <?php if ( 'selectbox' == bp_get_the_profile_field_type() ) : ?> 88 89 <label for="<?php bp_the_profile_field_input_name(); ?>"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php _e( '(required)', 'buddypress' ); ?><?php endif; ?></label> 90 <?php do_action( bp_get_the_profile_field_errors_action() ); ?> 91 <select name="<?php bp_the_profile_field_input_name(); ?>" id="<?php bp_the_profile_field_input_name(); ?>"> 92 <?php bp_the_profile_field_options(); ?> 93 </select> 94 95 <?php endif; ?> 96 97 <?php if ( 'multiselectbox' == bp_get_the_profile_field_type() ) : ?> 98 99 <label for="<?php bp_the_profile_field_input_name(); ?>"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php _e( '(required)', 'buddypress' ); ?><?php endif; ?></label> 100 <?php do_action( bp_get_the_profile_field_errors_action() ); ?> 101 <select name="<?php bp_the_profile_field_input_name(); ?>" id="<?php bp_the_profile_field_input_name(); ?>" multiple="multiple"> 102 <?php bp_the_profile_field_options(); ?> 103 </select> 104 105 <?php endif; ?> 106 107 <?php if ( 'radio' == bp_get_the_profile_field_type() ) : ?> 108 109 <div class="radio"> 110 <span class="label"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php _e( '(required)', 'buddypress' ); ?><?php endif; ?></span> 111 112 <?php do_action( bp_get_the_profile_field_errors_action() ); ?> 113 <?php bp_the_profile_field_options(); ?> 114 115 <?php if ( !bp_get_the_profile_field_is_required() ) : ?> 116 <a class="clear-value" href="javascript:clear( '<?php bp_the_profile_field_input_name(); ?>' );"><?php _e( 'Clear', 'buddypress' ); ?></a> 117 <?php endif; ?> 118 </div> 119 120 <?php endif; ?> 121 122 <?php if ( 'checkbox' == bp_get_the_profile_field_type() ) : ?> 123 124 <div class="checkbox"> 125 <span class="label"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php _e( '(required)', 'buddypress' ); ?><?php endif; ?></span> 126 127 <?php do_action( bp_get_the_profile_field_errors_action() ); ?> 128 <?php bp_the_profile_field_options(); ?> 129 </div> 130 131 <?php endif; ?> 132 133 <?php if ( 'datebox' == bp_get_the_profile_field_type() ) : ?> 134 135 <div class="datebox"> 136 <label for="<?php bp_the_profile_field_input_name(); ?>_day"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php _e( '(required)', 'buddypress' ); ?><?php endif; ?></label> 137 <?php do_action( bp_get_the_profile_field_errors_action() ); ?> 138 139 <select name="<?php bp_the_profile_field_input_name(); ?>_day" id="<?php bp_the_profile_field_input_name(); ?>_day"> 140 <?php bp_the_profile_field_options( 'type=day' ); ?> 141 </select> 142 143 <select name="<?php bp_the_profile_field_input_name(); ?>_month" id="<?php bp_the_profile_field_input_name(); ?>_month"> 144 <?php bp_the_profile_field_options( 'type=month' ); ?> 145 </select> 146 147 <select name="<?php bp_the_profile_field_input_name(); ?>_year" id="<?php bp_the_profile_field_input_name(); ?>_year"> 148 <?php bp_the_profile_field_options( 'type=year' ); ?> 149 </select> 150 </div> 151 152 <?php endif; ?> 153 154 <?php do_action( 'bp_custom_profile_edit_fields_pre_visibility' ); ?> 155 156 <?php if ( bp_current_user_can( 'bp_xprofile_change_field_visibility' ) ) : ?> 77 if ( bp_current_user_can( 'bp_xprofile_change_field_visibility' ) ) : ?> 157 78 <p class="field-visibility-settings-toggle" id="field-visibility-settings-toggle-<?php bp_the_profile_field_id() ?>"> 158 79 <?php printf( __( 'This field can be seen by: <span class="current-visibility-level">%s</span>', 'buddypress' ), bp_get_the_profile_field_visibility_level_label() ) ?> <a href="#" class="visibility-toggle-link"><?php _ex( 'Change', 'Change profile field visibility level', 'buddypress' ); ?></a> 159 80 </p> -
bp-templates/bp-legacy/buddypress/members/single/profile/edit.php
21 21 22 22 <div<?php bp_field_css_class( 'editfield' ); ?>> 23 23 24 <?php if ( 'textbox' == bp_get_the_profile_field_type() ) : ?> 24 <?php 25 $field_type = bp_xprofile_create_field_type( bp_get_the_profile_field_type() ); 26 $field_type->edit_field_html(); 25 27 26 <label for="<?php bp_the_profile_field_input_name(); ?>"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php _e( '(required)', 'buddypress' ); ?><?php endif; ?></label>27 <input type="text" name="<?php bp_the_profile_field_input_name(); ?>" id="<?php bp_the_profile_field_input_name(); ?>" value="<?php bp_the_profile_field_edit_value(); ?>" <?php if ( bp_get_the_profile_field_is_required() ) : ?>aria-required="true"<?php endif; ?>/>28 do_action( 'bp_custom_profile_edit_fields_pre_visibility' ); 29 ?> 28 30 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 118 31 <?php if ( bp_current_user_can( 'bp_xprofile_change_field_visibility' ) ) : ?> 119 32 <p class="field-visibility-settings-toggle" id="field-visibility-settings-toggle-<?php bp_the_profile_field_id() ?>"> 120 33 <?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
607 607 font-weight: bold; 608 608 margin: 15px 0 5px 0; 609 609 } 610 #buddypress .standard-form div.checkbox label ,611 #buddypress .standard-form div.radio label {610 #buddypress .standard-form div.checkbox label:nth-child(n+2), 611 #buddypress .standard-form div.radio div label { 612 612 color: #888; 613 613 font-size: 100%; 614 614 font-weight: normal; -
bp-xprofile/admin/js/admin.js
79 79 if ( !document.getElementById( id ) ) return false; 80 80 81 81 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 = ''; 83 85 } 84 86 85 87 var 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 1 function 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
382 382 <legend><span><?php bp_the_profile_field_name(); ?> <?php if( !$field->can_delete ) : ?> <?php _e( '(Primary)', 'buddypress' ); endif; ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php _e( '(Required)', 'buddypress' ) ?><?php endif; ?></span></legend> 383 383 <div class="field-wrapper"> 384 384 385 <?php switch ( $field->type ) : case 'textbox' : ?> 385 <?php 386 $field_type = bp_xprofile_create_field_type( $field->type ); 387 $field_type->admin_field_html(); 386 388 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 ?> 388 391 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 449 392 <?php if ( $field->description ) : ?> 450 393 451 394 <p class="description"><?php echo esc_attr( $field->description ); ?></p> … … 467 410 <?php 468 411 } 469 412 413 /** 414 * Print <option> elements containing the xprofile field types. 415 * 416 * @param string $select_field_type The name of the field type that should be selected. Will defaults to "textbox" if NULL is passed. 417 * @since BuddyPress (2.0.0) 418 */ 419 function bp_xprofile_admin_form_field_types( $select_field_type ) { 420 $categories = array(); 421 422 if ( is_null( $select_field_type ) ) { 423 $select_field_type = 'textbox'; 424 } 425 426 // Sort each field type into its category 427 foreach ( bp_xprofile_get_field_types() as $field_name => $field_class ) { 428 $field_type_obj = new $field_class; 429 $the_category = $field_type_obj->category; 430 431 // Fallback to a catch-all if category not set 432 if ( ! $the_category ) { 433 $the_category = _x( 'Other', 'xprofile field type category', 'buddypress' ); 434 } 435 436 if ( isset( $categories[$the_category] ) ) { 437 $categories[$the_category][] = array( $field_name, $field_type_obj ); 438 } else { 439 $categories[$the_category] = array( array( $field_name, $field_type_obj ) ); 440 } 441 } 442 443 // Sort the categories alphabetically. ksort()'s SORT_NATURAL is only in PHP >= 5.4 :(( 444 uksort( $categories, 'strnatcmp' ); 445 446 // Loop through each category and output form <options> 447 foreach ( $categories as $category => $fields ) { 448 printf( '<optgroup label="%1$s">', esc_attr( $category ) ); // Already i18n'd in each profile type class 449 450 // Sort these fields types alphabetically 451 uasort( $fields, create_function( '$a, $b', 'return strnatcmp( $a[1]->name, $b[1]->name );' ) ); 452 453 foreach ( $fields as $field_type_obj ) { 454 $field_name = $field_type_obj[0]; 455 $field_type_obj = $field_type_obj[1]; 456 457 printf( '<option value="%1$s" %2$s>%3$s</option>', esc_attr( $field_name ), selected( $select_field_type, $field_name, false ), esc_html( $field_type_obj->name ) ); 458 } 459 460 printf( '</optgroup>' ); 461 } 462 } 463 470 464 if ( ! class_exists( 'BP_XProfile_User_Admin' ) ) : 471 465 /** 472 466 * Load xProfile Profile admin area. … … 642 636 // Set the errors var 643 637 $errors = false; 644 638 645 // Now we've checked for required fields, let s save the values.639 // Now we've checked for required fields, let's save the values. 646 640 foreach ( (array) $posted_field_ids as $field_id ) { 647 641 648 642 // Certain types of fields (checkboxes, multiselects) may come through empty. Save them as an empty array so that they don't get overwritten by the default on the next edit. … … 702 696 } 703 697 704 698 if ( bp_has_profile( $r ) ) : 705 706 699 while ( bp_profile_groups() ) : bp_the_profile_group(); ?> 700 <input type="hidden" name="field_ids[]" id="<?php echo esc_attr( 'field_ids_' . bp_get_the_profile_group_slug() ); ?>" value="<?php echo esc_attr( bp_get_the_profile_group_field_ids() ); ?>" /> 707 701 708 <p class="description"><?php bp_the_profile_group_description(); ?></p> 702 <?php if ( bp_get_the_profile_group_description() ) : ?> 703 <p class="description"><?php bp_the_profile_group_description(); ?></p> 704 <?php 705 endif; 709 706 710 <table class="form-table"> 711 <tbody> 707 while ( bp_profile_fields() ) : bp_the_profile_field(); ?> 712 708 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'] ) ); 714 713 715 <tr> 714 if ( bp_get_the_profile_field_description() ) : ?> 715 <p class="description"><?php bp_the_profile_field_description(); ?></p> 716 <?php endif; 716 717 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 ?> 718 721 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() ); 724 725 726 if ( $can_change_visibility ) : ?> 727 <a href="#" class="button visibility-toggle-link"><?php _e( 'Change', 'buddypress' ); ?></a> 725 728 <?php endif; ?> 729 </p> 726 730 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; 728 740 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> 734 743 735 <?php endif; ?> 744 <?php 745 endwhile; // bp_profile_fields() 736 746 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"> </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() 868 748 endif; 869 749 } 870 750 -
bp-xprofile/bp-xprofile-classes.php
541 541 public $default_visibility = 'public'; 542 542 public $allow_custom_visibility = 'allowed'; 543 543 544 /** 545 * @since BuddyPress (2.0.0) 546 * @var BP_XProfile_Field_Type Field type object used for validation 547 */ 548 public $type_obj = null; 549 544 550 public $data; 545 551 public $message = null; 546 552 public $message_type = 'err'; 547 553 548 554 public function __construct( $id = null, $user_id = null, $get_data = true ) { 549 if ( !empty( $id ) ) 555 if ( !empty( $id ) ) { 550 556 $this->populate( $id, $user_id, $get_data ); 557 558 // Initialise the type obj to prevent fatals when creating new profile fields 559 } else { 560 $this->type_obj = bp_xprofile_create_field_type( 'textbox' ); 561 $this->type_obj->field_obj = $this; 562 } 551 563 } 552 564 553 565 public function populate( $id, $user_id, $get_data ) { … … 573 585 $this->order_by = $field->order_by; 574 586 $this->is_default_option = $field->is_default_option; 575 587 588 // Create the field type and store a reference back to this object. 589 $this->type_obj = bp_xprofile_create_field_type( $field->type ); 590 $this->type_obj->field_obj = $this; 591 576 592 if ( $get_data && $user_id ) { 577 593 $this->data = $this->get_field_data( $user_id ); 578 594 } … … 618 634 $this->order_by = apply_filters( 'xprofile_field_order_by_before_save', $this->order_by, $this->id ); 619 635 $this->field_order = apply_filters( 'xprofile_field_field_order_before_save', $this->field_order, $this->id ); 620 636 $this->can_delete = apply_filters( 'xprofile_field_can_delete_before_save', $this->can_delete, $this->id ); 637 $this->type_obj = bp_xprofile_create_field_type( $this->type ); 621 638 622 639 do_action_ref_array( 'xprofile_field_before_save', array( $this ) ); 623 640 … … 655 672 * Check to see if this is a field with child options. 656 673 * We need to add the options to the db, if it is. 657 674 */ 658 if ( 'radio' == $this->type || 'selectbox' == $this->type || 'checkbox' == $this->type || 'multiselectbox' == $this->type) {675 if ( $this->type_obj->supports_options ) { 659 676 660 677 if ( !empty( $this->id ) ) { 661 678 $parent_id = $this->id; … … 663 680 $parent_id = $wpdb->insert_id; 664 681 } 665 682 666 if ( 'radio' == $this->type ) { 667 $post_option = !empty( $_POST['radio_option'] ) ? $_POST['radio_option'] : ''; 668 $post_default = !empty( $_POST['isDefault_radio_option'] ) ? $_POST['isDefault_radio_option'] : ''; 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 ); 669 688 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 695 689 $counter = 1; 696 690 if ( !empty( $options ) ) { 697 691 foreach ( (array) $options as $option_key => $option_value ) { … … 718 712 719 713 do_action_ref_array( 'xprofile_field_after_save', array( $this ) ); 720 714 715 // Recreate type_obj in case someone changed $this->type via a filter 716 $this->type_obj = bp_xprofile_create_field_type( $this->type ); 717 $this->type_obj->field_obj = $this; 718 721 719 return $field_id; 722 720 } else { 723 721 return false; … … 824 822 return false; 825 823 } 826 824 827 /* ADMIN AREA HTML. 828 * TODO: Get this out of here and replace with standard template loops 829 */ 830 831 /* This function populates the items for radio buttons checkboxes and drop down boxes */ 825 /** 826 * This function populates the items for radio buttons checkboxes and drop down boxes 827 */ 832 828 public function render_admin_form_children() { 833 $input_types = array( 'checkbox', 'selectbox', 'multiselectbox', 'radio' ); 834 835 foreach ( $input_types as $type ) { 836 $default_name = ''; 837 838 if ( ( 'multiselectbox' == $type ) || ( 'checkbox' == $type ) ) { 839 $default_input = 'checkbox'; 840 } else { 841 $default_input = 'radio'; 842 } 843 844 $class = $this->type != $type ? 'display: none;' : ''; 845 846 if ( empty( $this->default_visibility ) ) { 847 $this->default_visibility = 'public'; 848 } 849 850 ?> 851 852 <div id="<?php echo esc_attr( $type ); ?>" class="postbox bp-options-box" style="<?php echo esc_attr( $class ); ?> margin-top: 15px;"> 853 <h3><?php _e( 'Please enter options for this Field:', 'buddypress' ); ?></h3> 854 <div class="inside"> 855 <p> 856 <label for="sort_order_<?php echo esc_attr( $type ); ?>"><?php _e( 'Sort Order:', 'buddypress' ); ?></label> 857 <select name="sort_order_<?php echo esc_attr( $type ); ?>" id="sort_order_<?php echo esc_attr( $type ); ?>" > 858 <option value="custom" <?php selected( 'custom', $this->order_by ); ?>><?php _e( 'Custom', 'buddypress' ); ?></option> 859 <option value="asc" <?php selected( 'asc', $this->order_by ); ?>><?php _e( 'Ascending', 'buddypress' ); ?></option> 860 <option value="desc" <?php selected( 'desc', $this->order_by ); ?>><?php _e( 'Descending', 'buddypress' ); ?></option> 861 </select> 862 </p> 863 864 <?php if ( !$options = $this->get_children( true ) ) { 865 866 $i = 1; 867 while ( isset( $_POST[$type . '_option'][$i] ) ) { 868 (array) $options[] = (object) array( 869 'id' => -1, 870 'name' => $_POST[$type . '_option'][$i], 871 'is_default_option' => ( ( 'multiselectbox' != $type ) && ( 'checkbox' != $type ) && ( $_POST["isDefault_{$type}_option"] == $i ) ) ? 1 : $_POST["isDefault_{$type}_option"][$i] 872 ); 873 874 ++$i; 875 } 876 } 877 878 if ( !empty( $options ) ) { 879 for ( $i = 0, $count = count( $options ); $i < $count; ++$i ) { 880 $j = $i + 1; 881 882 if ( 'multiselectbox' == $type || 'checkbox' == $type ) 883 $default_name = '[' . $j . ']'; ?> 884 885 <p class="sortable"> 886 <span> Ξ </span> 887 <input type="text" name="<?php echo esc_attr( $type ); ?>_option[<?php echo esc_attr( $j ); ?>]" id="<?php echo esc_attr( $type ); ?>_option<?php echo esc_attr( $j ); ?>" value="<?php echo stripslashes( esc_attr( $options[$i]->name ) ); ?>" /> 888 <input type="<?php echo $default_input; ?>" name="isDefault_<?php echo esc_attr( $type ); ?>_option<?php echo esc_attr( $default_name ); ?>" <?php checked( (int) $options[$i]->is_default_option, true ); ?> value="<?php echo esc_attr( $j ); ?>" /> 889 <span><?php _e( 'Default Value', 'buddypress' ); ?></span> 890 <a href="<?php echo esc_url( 'users.php?page=bp-profile-setup&mode=delete_option&option_id=' . $options[$i]->id ); ?>" class="ajax-option-delete" id="delete-<?php echo esc_attr( $options[$i]->id ); ?>">[x]</a> 891 </p> 892 893 <?php } /* end for */ ?> 894 895 <input type="hidden" name="<?php echo esc_attr( $type ); ?>_option_number" id="<?php echo esc_attr( $type ); ?>_option_number" value="<?php echo esc_attr( (int) $j + 1 ); ?>" /> 896 897 <?php } else { 898 899 if ( 'multiselectbox' == $type || 'checkbox' == $type ) 900 $default_name = '[1]'; ?> 901 902 <p class="sortable"> 903 <span> Ξ </span> 904 <input type="text" name="<?php echo esc_attr( $type ); ?>_option[1]" id="<?php echo esc_attr( $type ); ?>_option1" /> 905 <input type="<?php echo esc_attr( $default_input ); ?>" name="isDefault_<?php echo esc_attr( $type ); ?>_option<?php echo esc_attr( $default_name ); ?>" id="isDefault_<?php echo esc_attr( $type ); ?>_option" value="1" /> 906 <span><?php _e( 'Default Value', 'buddypress' ); ?></span> 907 <input type="hidden" name="<?php echo esc_attr( $type ); ?>_option_number" id="<?php echo esc_attr( $type ); ?>_option_number" value="2" /> 908 </p> 909 910 <?php } /* end if */ ?> 911 912 <div id="<?php echo esc_attr( $type ); ?>_more"></div> 913 <p><a href="javascript:add_option('<?php echo esc_attr( $type ); ?>')"><?php _e( 'Add Another Option', 'buddypress' ); ?></a></p> 914 </div> 915 </div> 916 917 <?php } 829 foreach ( array_keys( bp_xprofile_get_field_types() ) as $field_type ) { 830 $type_obj = bp_xprofile_create_field_type( $field_type ); 831 $type_obj->admin_new_field_html( $this ); 832 } 918 833 } 919 834 920 835 public function render_admin_form( $message = '' ) { … … 1041 956 <h3><label for="fieldtype"><?php _e( 'Field Type', 'buddypress'); ?></label></h3> 1042 957 <div class="inside"> 1043 958 <select name="fieldtype" id="fieldtype" onchange="show_options(this.value)" style="width: 30%"> 1044 <optgroup label="<?php esc_attr_e( 'Single Fields', 'buddypress' ); ?>"> 1045 <option value="textbox" <?php selected( $this->type, 'textbox' ); ?>><?php _e( 'Text Box', 'buddypress' ); ?></option> 1046 <option value="textarea" <?php selected( $this->type, 'textarea' ); ?>><?php _e( 'Multi-line Text Area', 'buddypress' ); ?></option> 1047 <option value="datebox" <?php selected( $this->type, 'datebox' ); ?>><?php _e( 'Date Selector', 'buddypress' ); ?></option> 1048 </optgroup> 1049 <optgroup label="<?php esc_attr_e( 'Multi Fields', 'buddypress' ); ?>"> 1050 <option value="radio" <?php selected( $this->type, 'radio' ); ?>><?php _e( 'Radio Buttons', 'buddypress' ); ?></option> 1051 <option value="selectbox" <?php selected( $this->type, 'selectbox' ); ?>><?php _e( 'Drop Down Select Box', 'buddypress' ); ?></option> 1052 <option value="multiselectbox" <?php selected( $this->type, 'multiselectbox' ); ?>><?php _e( 'Multi Select Box', 'buddypress' ); ?></option> 1053 <option value="checkbox" <?php selected( $this->type, 'checkbox' ); ?>><?php _e( 'Checkboxes', 'buddypress' ); ?></option> 1054 </optgroup> 959 <?php bp_xprofile_admin_form_field_types( $this->type ); ?> 1055 960 </select> 1056 961 1057 <?php do_action_ref_array( 'xprofile_field_additional_options', array( $this ) ); ?> 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 ); 1058 965 1059 <?php $this->render_admin_form_children(); ?>1060 966 $this->render_admin_form_children(); 967 ?> 1061 968 </div> 1062 969 </div> 1063 970 … … 1086 993 if ( '' == $_POST['title'] || '' == $_POST['required'] || '' == $_POST['fieldtype'] ) { 1087 994 $message = __( 'Please make sure you fill out all required fields.', 'buddypress' ); 1088 995 return false; 1089 } else if ( empty( $_POST['field_file'] ) && $_POST['fieldtype'] == 'radio' && empty( $_POST['radio_option'][1] ) ) { 1090 $message = __( 'Radio button field types require at least one option. Please add options below.', 'buddypress' ); 1091 return false; 1092 } else if ( empty( $_POST['field_file'] ) && $_POST['fieldtype'] == 'selectbox' && empty( $_POST['selectbox_option'][1] ) ) { 1093 $message = __( 'Select box field types require at least one option. Please add options below.', 'buddypress' ); 1094 return false; 1095 } else if ( empty( $_POST['field_file'] ) && $_POST['fieldtype'] == 'multiselectbox' && empty( $_POST['multiselectbox_option'][1] ) ) { 1096 $message = __( 'Select box field types require at least one option. Please add options below.', 'buddypress' ); 1097 return false; 1098 } else if ( empty( $_POST['field_file'] ) && $_POST['fieldtype'] == 'checkbox' && empty( $_POST['checkbox_option'][1] ) ) { 1099 $message = __( 'Checkbox field types require at least one option. Please add options below.', 'buddypress' ); 1100 return false; 1101 } else { 1102 return true; 996 997 } elseif ( empty( $_POST['field_file'] ) ) { 998 $field_type = bp_xprofile_create_field_type( $_POST['fieldtype'] ); 999 $option_name = "{$_POST['fieldtype']}_option"; 1000 1001 if ( $field_type->supports_options && isset( $_POST[$option_name] ) && empty( $_POST[$option_name][1] ) ) { 1002 $message = __( 'This field type require at least one option. Please add options below.', 'buddypress' ); 1003 return false; 1004 } 1103 1005 } 1006 1007 return true; 1104 1008 } 1105 1009 } 1106 1010 1107 1108 1011 class BP_XProfile_ProfileData { 1109 1012 public $id; 1110 1013 public $user_id; … … 1540 1443 return $data[$field_name]; 1541 1444 } 1542 1445 } 1446 1447 /** 1448 * Datebox xprofile field type. 1449 * 1450 * @since BuddyPress (2.0.0) 1451 */ 1452 class BP_XProfile_Field_Type_Datebox extends BP_XProfile_Field_Type { 1453 1454 /** 1455 * Constructor for the datebox field type 1456 * 1457 * @since BuddyPress (2.0.0) 1458 */ 1459 public function __construct() { 1460 parent::__construct(); 1461 1462 $this->category = _x( 'Single Fields', 'xprofile field type category', 'buddypress' ); 1463 $this->name = _x( 'Date Selector', 'xprofile field type', 'buddypress' ); 1464 1465 $this->set_format( '/^\d{4}-\d{1,2}-\d{1,2} 00:00:00$/', 'replace' ); // "Y-m-d 00:00:00" 1466 do_action( 'bp_xprofile_field_type_datebox', $this ); 1467 } 1468 1469 /** 1470 * Output the edit field HTML for this field type. 1471 * 1472 * Must be used inside the {@link bp_profile_fields()} template loop. 1473 * 1474 * @param array $raw_properties Optional key/value array of {@link http://dev.w3.org/html5/markup/input.html permitted attributes} that you want to add. 1475 * @since BuddyPress (2.0.0) 1476 */ 1477 public function edit_field_html( array $raw_properties = array() ) { 1478 $user_id = bp_displayed_user_id(); 1479 1480 // user_id is a special optional parameter that we pass to {@link bp_the_profile_field_options()}. 1481 if ( isset( $raw_properties['user_id'] ) ) { 1482 $user_id = (int) $raw_properties['user_id']; 1483 unset( $raw_properties['user_id'] ); 1484 } 1485 1486 $day_html = $this->get_edit_field_html_elements( array_merge( 1487 array( 1488 'id' => bp_get_the_profile_field_input_name() . '_day', 1489 'name' => bp_get_the_profile_field_input_name() . '_day', 1490 ), 1491 $raw_properties 1492 ) ); 1493 1494 $month_html = $this->get_edit_field_html_elements( array_merge( 1495 array( 1496 'id' => bp_get_the_profile_field_input_name() . '_month', 1497 'name' => bp_get_the_profile_field_input_name() . '_month', 1498 ), 1499 $raw_properties 1500 ) ); 1501 1502 $year_html = $this->get_edit_field_html_elements( array_merge( 1503 array( 1504 'id' => bp_get_the_profile_field_input_name() . '_year', 1505 'name' => bp_get_the_profile_field_input_name() . '_year', 1506 ), 1507 $raw_properties 1508 ) ); 1509 ?> 1510 <div class="datebox"> 1511 1512 <label for="<?php bp_the_profile_field_input_name(); ?>_day"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php esc_html_e( '(required)', 'buddypress' ); ?><?php endif; ?></label> 1513 1514 <select <?php echo $day_html; ?>> 1515 <?php bp_the_profile_field_options( array( 'type' => 'day', 'user_id' => $user_id ) ); ?> 1516 </select> 1517 1518 <select <?php echo $month_html; ?>> 1519 <?php bp_the_profile_field_options( array( 'type' => 'month', 'user_id' => $user_id ) ); ?> 1520 </select> 1521 1522 <select <?php echo $year_html; ?>> 1523 <?php bp_the_profile_field_options( array( 'type' => 'year', 'user_id' => $user_id ) ); ?> 1524 </select> 1525 1526 </div> 1527 <?php 1528 } 1529 1530 /** 1531 * Output the edit field options HTML for this field type. 1532 * 1533 * BuddyPress considers a field's "options" to be, for example, the items in a selectbox. 1534 * These are stored separately in the database, and their templating is handled seperately. 1535 * 1536 * This templating is separate from {@link BP_XProfile_Field_Type::edit_field_html()} because 1537 * it's also used in the wp-admin screens when creating new fields, and for backwards compatibility. 1538 * 1539 * Must be used inside the {@link bp_profile_fields()} template loop. 1540 * 1541 * @param array $args Optional. The arguments passed to {@link bp_the_profile_field_options()}. 1542 * @since BuddyPress (2.0.0) 1543 */ 1544 public function edit_field_options_html( array $args = array() ) { 1545 $options = $this->field_obj->get_children(); 1546 $date = BP_XProfile_ProfileData::get_value_byid( $this->field_obj->id, $args['user_id'] ); 1547 1548 $day = 0; 1549 $month = 0; 1550 $year = 0; 1551 $html = ''; 1552 1553 // Set day, month, year defaults 1554 if ( ! empty( $date ) ) { 1555 1556 // If Unix timestamp 1557 if ( is_numeric( $date ) ) { 1558 $day = date( 'j', $date ); 1559 $month = date( 'F', $date ); 1560 $year = date( 'Y', $date ); 1561 1562 // If MySQL timestamp 1563 } else { 1564 $day = mysql2date( 'j', $date ); 1565 $month = mysql2date( 'F', $date, false ); // Not localized, so that selected() works below 1566 $year = mysql2date( 'Y', $date ); 1567 } 1568 } 1569 1570 // Check for updated posted values, and errors preventing them from being saved first time. 1571 if ( ! empty( $_POST['field_' . $this->field_obj->id . '_day'] ) ) { 1572 $new_day = (int) $_POST['field_' . $this->field_obj->id . '_day']; 1573 $day = ( $day != $new_day ) ? $new_day : $day; 1574 } 1575 1576 if ( ! empty( $_POST['field_' . $this->field_obj->id . '_month'] ) ) { 1577 $new_month = (int) $_POST['field_' . $this->field_obj->id . '_month']; 1578 $month = ( $month != $new_month ) ? $new_month : $month; 1579 } 1580 1581 if ( ! empty( $_POST['field_' . $this->field_obj->id . '_year'] ) ) { 1582 $new_year = date( 'j', (int) $_POST['field_' . $this->field_obj->id . '_year'] ); 1583 $year = ( $year != $new_year ) ? $new_year : $year; 1584 } 1585 1586 // $type will be passed by calling function when needed 1587 switch ( $args['type'] ) { 1588 case 'day': 1589 $html = sprintf( '<option value="" %1$s>%2$s</option>', selected( $day, 0, false ), /* translators: no option picked in select box */ __( '----', 'buddypress' ) ); 1590 1591 for ( $i = 1; $i < 32; ++$i ) { 1592 $html .= sprintf( '<option value="%1$s" %2$s>%3$s</option>', (int) $i, selected( $day, $i, false ), (int) $i ); 1593 } 1594 break; 1595 1596 case 'month': 1597 $eng_months = array( 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ); 1598 1599 $months = array( 1600 __( 'January', 'buddypress' ), 1601 __( 'February', 'buddypress' ), 1602 __( 'March', 'buddypress' ), 1603 __( 'April', 'buddypress' ), 1604 __( 'May', 'buddypress' ), 1605 __( 'June', 'buddypress' ), 1606 __( 'July', 'buddypress' ), 1607 __( 'August', 'buddypress' ), 1608 __( 'September', 'buddypress' ), 1609 __( 'October', 'buddypress' ), 1610 __( 'November', 'buddypress' ), 1611 __( 'December', 'buddypress' ) 1612 ); 1613 1614 $html = sprintf( '<option value="" %1$s>%2$s</option>', selected( $month, 0, false ), /* translators: no option picked in select box */ __( '----', 'buddypress' ) ); 1615 1616 for ( $i = 0; $i < 12; ++$i ) { 1617 $html .= sprintf( '<option value="%1$s" %2$s>%3$s</option>', esc_attr( $eng_months[$i] ), selected( $month, $eng_months[$i], false ), $months[$i] ); 1618 } 1619 break; 1620 1621 case 'year': 1622 $html = sprintf( '<option value="" %1$s>%2$s</option>', selected( $year, 0, false ), /* translators: no option picked in select box */ __( '----', 'buddypress' ) ); 1623 1624 for ( $i = 2037; $i > 1901; $i-- ) { 1625 $html .= sprintf( '<option value="%1$s" %2$s>%3$s</option>', (int) $i, selected( $year, $i, false ), (int) $i ); 1626 } 1627 break; 1628 } 1629 1630 echo apply_filters( 'bp_get_the_profile_field_datebox', $html, $args['type'], $day, $month, $year, $this->field_obj->id, $date ); 1631 } 1632 1633 /** 1634 * Output HTML for this field type on the wp-admin Profile Fields screen. 1635 * 1636 * Must be used inside the {@link bp_profile_fields()} template loop. 1637 * 1638 * @param array $raw_properties Optional key/value array of permitted attributes that you want to add. 1639 * @since BuddyPress (2.0.0) 1640 */ 1641 public function admin_field_html( array $raw_properties = array() ) { 1642 $day_html = $this->get_edit_field_html_elements( array_merge( 1643 array( 1644 'id' => bp_get_the_profile_field_input_name() . '_day', 1645 'name' => bp_get_the_profile_field_input_name() . '_day', 1646 ), 1647 $raw_properties 1648 ) ); 1649 1650 $month_html = $this->get_edit_field_html_elements( array_merge( 1651 array( 1652 'id' => bp_get_the_profile_field_input_name() . '_month', 1653 'name' => bp_get_the_profile_field_input_name() . '_month', 1654 ), 1655 $raw_properties 1656 ) ); 1657 1658 $year_html = $this->get_edit_field_html_elements( array_merge( 1659 array( 1660 'id' => bp_get_the_profile_field_input_name() . '_year', 1661 'name' => bp_get_the_profile_field_input_name() . '_year', 1662 ), 1663 $raw_properties 1664 ) ); 1665 ?> 1666 <select <?php echo $day_html; ?>> 1667 <?php bp_the_profile_field_options( 'type=day' ); ?> 1668 </select> 1669 1670 <select <?php echo $month_html; ?>> 1671 <?php bp_the_profile_field_options( 'type=month' ); ?> 1672 </select> 1673 1674 <select <?php echo $year_html; ?>> 1675 <?php bp_the_profile_field_options( 'type=year' ); ?> 1676 </select> 1677 <?php 1678 } 1679 1680 /** 1681 * This method usually outputs HTML for this field type's children options on the wp-admin Profile Fields 1682 * "Add Field" and "Edit Field" screens, but for this field type, we don't want it, so it's stubbed out. 1683 * 1684 * @param BP_XProfile_Field $current_field The current profile field on the add/edit screen. 1685 * @param string $control_type Optional. HTML input type used to render the current field's child options. 1686 * @since BuddyPress (2.0.0) 1687 */ 1688 public function admin_new_field_html( BP_XProfile_Field $current_field, $control_type = '' ) {} 1689 } 1690 1691 /** 1692 * Checkbox xprofile field type. 1693 * 1694 * @since BuddyPress (2.0.0) 1695 */ 1696 class BP_XProfile_Field_Type_Checkbox extends BP_XProfile_Field_Type { 1697 1698 /** 1699 * Constructor for the checkbox field type 1700 * 1701 * @since BuddyPress (2.0.0) 1702 */ 1703 public function __construct() { 1704 parent::__construct(); 1705 1706 $this->category = _x( 'Multi Fields', 'xprofile field type category', 'buddypress' ); 1707 $this->name = _x( 'Checkboxes', 'xprofile field type', 'buddypress' ); 1708 1709 $this->supports_multiple_defaults = true; 1710 $this->accepts_null_value = true; 1711 $this->supports_options = true; 1712 1713 $this->set_format( '/^.+$/', 'replace' ); 1714 do_action( 'bp_xprofile_field_type_checkbox', $this ); 1715 } 1716 1717 /** 1718 * Output the edit field HTML for this field type. 1719 * 1720 * Must be used inside the {@link bp_profile_fields()} template loop. 1721 * 1722 * @param array $raw_properties Optional key/value array of {@link http://dev.w3.org/html5/markup/input.checkbox.html permitted attributes} that you want to add. 1723 * @since BuddyPress (2.0.0) 1724 */ 1725 public function edit_field_html( array $raw_properties = array() ) { 1726 $user_id = bp_displayed_user_id(); 1727 1728 // user_id is a special optional parameter that we pass to {@link bp_the_profile_field_options()}. 1729 if ( isset( $raw_properties['user_id'] ) ) { 1730 $user_id = (int) $raw_properties['user_id']; 1731 unset( $raw_properties['user_id'] ); 1732 } 1733 ?> 1734 <div class="checkbox"> 1735 1736 <label for="<?php bp_the_profile_field_input_name(); ?>"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php esc_html_e( '(required)', 'buddypress' ); ?><?php endif; ?></label> 1737 <?php bp_the_profile_field_options( "user_id={$user_id}" ); ?> 1738 1739 </div> 1740 <?php 1741 } 1742 1743 /** 1744 * Output the edit field options HTML for this field type. 1745 * 1746 * BuddyPress considers a field's "options" to be, for example, the items in a selectbox. 1747 * These are stored separately in the database, and their templating is handled seperately. 1748 * 1749 * This templating is separate from {@link BP_XProfile_Field_Type::edit_field_html()} because 1750 * it's also used in the wp-admin screens when creating new fields, and for backwards compatibility. 1751 * 1752 * Must be used inside the {@link bp_profile_fields()} template loop. 1753 * 1754 * @param array $args Optional. The arguments passed to {@link bp_the_profile_field_options()}. 1755 * @since BuddyPress (2.0.0) 1756 */ 1757 public function edit_field_options_html( array $args = array() ) { 1758 $options = $this->field_obj->get_children(); 1759 $option_values = BP_XProfile_ProfileData::get_value_byid( $this->field_obj->id, $args['user_id'] ); 1760 $option_values = (array) maybe_unserialize( $option_values ); 1761 1762 $html = ''; 1763 1764 // Check for updated posted values, but errors preventing them from being saved first time 1765 if ( isset( $_POST['field_' . $this->field_obj->id] ) && $option_values != maybe_serialize( $_POST['field_' . $this->field_obj->id] ) ) { 1766 if ( ! empty( $_POST['field_' . $this->field_obj->id] ) ) { 1767 $option_values = array_map( 'sanitize_text_field', $_POST['field_' . $this->field_obj->id] ); 1768 } 1769 } 1770 1771 for ( $k = 0, $count = count( $options ); $k < $count; ++$k ) { 1772 $selected = ''; 1773 1774 // First, check to see whether the user's saved values match the option 1775 for ( $j = 0, $count_values = count( $option_values ); $j < $count_values; ++$j ) { 1776 1777 // Run the allowed option name through the before_save filter, so we'll be sure to get a match 1778 $allowed_options = xprofile_sanitize_data_value_before_save( $options[$k]->name, false, false ); 1779 1780 if ( $option_values[$j] === $allowed_options || in_array( $allowed_options, $option_values ) ) { 1781 $selected = ' checked="checked"'; 1782 break; 1783 } 1784 } 1785 1786 // If the user has not yet supplied a value for this field, check to see whether there is a default value available 1787 if ( ! is_array( $option_values ) && empty( $option_values ) && empty( $selected ) && ! empty( $options[$k]->is_default_option ) ) { 1788 $selected = ' checked="checked"'; 1789 } 1790 1791 $new_html = sprintf( '<label><input %1$s type="checkbox" name="%2$s" id="%3$s" value="%4$s">%5$s</label>', 1792 $selected, 1793 esc_attr( "field_{$this->field_obj->id}[]" ), 1794 esc_attr( "field_{$options[$k]->id}_{$k}" ), 1795 esc_attr( stripslashes( $options[$k]->name ) ), 1796 esc_html( stripslashes( $options[$k]->name ) ) 1797 ); 1798 $html .= apply_filters( 'bp_get_the_profile_field_options_checkbox', $new_html, $options[$k], $this->field_obj->id, $selected, $k ); 1799 } 1800 1801 echo $html; 1802 } 1803 1804 /** 1805 * Output HTML for this field type on the wp-admin Profile Fields screen. 1806 * 1807 * Must be used inside the {@link bp_profile_fields()} template loop. 1808 * 1809 * @param array $raw_properties Optional key/value array of permitted attributes that you want to add. 1810 * @since BuddyPress (2.0.0) 1811 */ 1812 public function admin_field_html( array $raw_properties = array() ) { 1813 bp_the_profile_field_options(); 1814 } 1815 1816 /** 1817 * Output HTML for this field type's children options on the wp-admin Profile Fields "Add Field" and "Edit Field" screens. 1818 * 1819 * Must be used inside the {@link bp_profile_fields()} template loop. 1820 * 1821 * @param BP_XProfile_Field $current_field The current profile field on the add/edit screen. 1822 * @param string $control_type Optional. HTML input type used to render the current field's child options. 1823 * @since BuddyPress (2.0.0) 1824 */ 1825 public function admin_new_field_html( BP_XProfile_Field $current_field, $control_type = '' ) { 1826 parent::admin_new_field_html( $current_field, 'checkbox' ); 1827 } 1828 } 1829 1830 /** 1831 * Radio button xprofile field type. 1832 * 1833 * @since BuddyPress (2.0.0) 1834 */ 1835 class BP_XProfile_Field_Type_Radiobutton extends BP_XProfile_Field_Type { 1836 1837 /** 1838 * Constructor for the radio button field type 1839 * 1840 * @since BuddyPress (2.0.0) 1841 */ 1842 public function __construct() { 1843 parent::__construct(); 1844 1845 $this->category = _x( 'Multi Fields', 'xprofile field type category', 'buddypress' ); 1846 $this->name = _x( 'Radio Buttons', 'xprofile field type', 'buddypress' ); 1847 1848 $this->supports_options = true; 1849 1850 $this->set_format( '/^.+$/', 'replace' ); 1851 do_action( 'bp_xprofile_field_type_radiobutton', $this ); 1852 } 1853 1854 /** 1855 * Output the edit field HTML for this field type. 1856 * 1857 * Must be used inside the {@link bp_profile_fields()} template loop. 1858 * 1859 * @param array $raw_properties Optional key/value array of {@link http://dev.w3.org/html5/markup/input.radio.html permitted attributes} that you want to add. 1860 * @since BuddyPress (2.0.0) 1861 */ 1862 public function edit_field_html( array $raw_properties = array() ) { 1863 $user_id = bp_displayed_user_id(); 1864 1865 // user_id is a special optional parameter that we pass to {@link bp_the_profile_field_options()}. 1866 if ( isset( $raw_properties['user_id'] ) ) { 1867 $user_id = (int) $raw_properties['user_id']; 1868 unset( $raw_properties['user_id'] ); 1869 } 1870 ?> 1871 <div class="radio"> 1872 1873 <label for="<?php bp_the_profile_field_input_name(); ?>"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php esc_html_e( '(required)', 'buddypress' ); ?><?php endif; ?></label> 1874 <?php bp_the_profile_field_options( "user_id={$user_id}" ); 1875 1876 if ( ! bp_get_the_profile_field_is_required() ) : ?> 1877 <a class="clear-value" href="javascript:clear( '<?php echo esc_js( bp_get_the_profile_field_input_name() ); ?>' );"><?php esc_html_e( 'Clear', 'buddypress' ); ?></a> 1878 <?php endif; ?> 1879 1880 </div> 1881 <?php 1882 } 1883 1884 /** 1885 * Output the edit field options HTML for this field type. 1886 * 1887 * BuddyPress considers a field's "options" to be, for example, the items in a selectbox. 1888 * These are stored separately in the database, and their templating is handled seperately. 1889 * 1890 * This templating is separate from {@link BP_XProfile_Field_Type::edit_field_html()} because 1891 * it's also used in the wp-admin screens when creating new fields, and for backwards compatibility. 1892 * 1893 * Must be used inside the {@link bp_profile_fields()} template loop. 1894 * 1895 * @param array $args Optional. The arguments passed to {@link bp_the_profile_field_options()}. 1896 * @since BuddyPress (2.0.0) 1897 */ 1898 public function edit_field_options_html( array $args = array() ) { 1899 $option_value = BP_XProfile_ProfileData::get_value_byid( $this->field_obj->id, $args['user_id'] ); 1900 $options = $this->field_obj->get_children(); 1901 1902 $html = sprintf( '<div id="%s">', esc_attr( 'field_' . $this->field_obj->id ) ); 1903 1904 for ( $k = 0, $count = count( $options ); $k < $count; ++$k ) { 1905 1906 // Check for updated posted values, but errors preventing them from being saved first time 1907 if ( isset( $_POST['field_' . $this->field_obj->id] ) && $option_value != $_POST['field_' . $this->field_obj->id] ) { 1908 if ( ! empty( $_POST['field_' . $this->field_obj->id] ) ) { 1909 $option_value = sanitize_text_field( $_POST['field_' . $this->field_obj->id] ); 1910 } 1911 } 1912 1913 // Run the allowed option name through the before_save filter, so we'll be sure to get a match 1914 $allowed_options = xprofile_sanitize_data_value_before_save( $options[$k]->name, false, false ); 1915 $selected = ''; 1916 1917 if ( $option_value === $allowed_options || ( empty( $option_value ) && ! empty( $options[$k]->is_default_option ) ) ) { 1918 $selected = ' checked="checked"'; 1919 } 1920 1921 $new_html = sprintf( '<label><input %1$s type="radio" name="%2$s" id="%3$s" value="%4$s">%5$s</label>', 1922 $selected, 1923 esc_attr( "field_{$this->field_obj->id}" ), 1924 esc_attr( "option_{$options[$k]->id}" ), 1925 esc_attr( stripslashes( $options[$k]->name ) ), 1926 esc_html( stripslashes( $options[$k]->name ) ) 1927 ); 1928 $html .= apply_filters( 'bp_get_the_profile_field_options_radio', $new_html, $options[$k], $this->field_obj->id, $selected, $k ); 1929 } 1930 1931 echo $html . '</div>'; 1932 } 1933 1934 /** 1935 * Output HTML for this field type on the wp-admin Profile Fields screen. 1936 * 1937 * Must be used inside the {@link bp_profile_fields()} template loop. 1938 * 1939 * @param array $raw_properties Optional key/value array of permitted attributes that you want to add. 1940 * @since BuddyPress (2.0.0) 1941 */ 1942 public function admin_field_html( array $raw_properties = array() ) { 1943 bp_the_profile_field_options(); 1944 1945 if ( ! bp_get_the_profile_field_is_required() ) : ?> 1946 <a class="clear-value" href="javascript:clear( '<?php echo esc_js( bp_get_the_profile_field_input_name() ); ?>' );"><?php esc_html_e( 'Clear', 'buddypress' ); ?></a> 1947 <?php endif; ?> 1948 <?php 1949 } 1950 1951 /** 1952 * Output HTML for this field type's children options on the wp-admin Profile Fields "Add Field" and "Edit Field" screens. 1953 * 1954 * Must be used inside the {@link bp_profile_fields()} template loop. 1955 * 1956 * @param BP_XProfile_Field $current_field The current profile field on the add/edit screen. 1957 * @param string $control_type Optional. HTML input type used to render the current field's child options. 1958 * @since BuddyPress (2.0.0) 1959 */ 1960 public function admin_new_field_html( BP_XProfile_Field $current_field, $control_type = '' ) { 1961 parent::admin_new_field_html( $current_field, 'radio' ); 1962 } 1963 } 1964 1965 /** 1966 * Multi-selectbox xprofile field type. 1967 * 1968 * @since BuddyPress (2.0.0) 1969 */ 1970 class BP_XProfile_Field_Type_Multiselectbox extends BP_XProfile_Field_Type { 1971 1972 /** 1973 * Constructor for the multi-selectbox field type 1974 * 1975 * @since BuddyPress (2.0.0) 1976 */ 1977 public function __construct() { 1978 parent::__construct(); 1979 1980 $this->category = _x( 'Multi Fields', 'xprofile field type category', 'buddypress' ); 1981 $this->name = _x( 'Multi Select Box', 'xprofile field type', 'buddypress' ); 1982 1983 $this->supports_multiple_defaults = true; 1984 $this->accepts_null_value = true; 1985 $this->supports_options = true; 1986 1987 $this->set_format( '/^.+$/', 'replace' ); 1988 do_action( 'bp_xprofile_field_type_multiselectbox', $this ); 1989 } 1990 1991 /** 1992 * Output the edit field HTML for this field type. 1993 * 1994 * Must be used inside the {@link bp_profile_fields()} template loop. 1995 * 1996 * @param array $raw_properties Optional key/value array of {@link http://dev.w3.org/html5/markup/select.html permitted attributes} that you want to add. 1997 * @since BuddyPress (2.0.0) 1998 */ 1999 public function edit_field_html( array $raw_properties = array() ) { 2000 $user_id = bp_displayed_user_id(); 2001 2002 // user_id is a special optional parameter that we pass to {@link bp_the_profile_field_options()}. 2003 if ( isset( $raw_properties['user_id'] ) ) { 2004 $user_id = (int) $raw_properties['user_id']; 2005 unset( $raw_properties['user_id'] ); 2006 } 2007 2008 $html = $this->get_edit_field_html_elements( array_merge( 2009 array( '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 */ 2119 class BP_XProfile_Field_Type_Selectbox extends BP_XProfile_Field_Type { 2120 2121 /** 2122 * Constructor for the selectbox field type 2123 * 2124 * @since BuddyPress (2.0.0) 2125 */ 2126 public function __construct() { 2127 parent::__construct(); 2128 2129 $this->category = _x( 'Multi Fields', 'xprofile field type category', 'buddypress' ); 2130 $this->name = _x( 'Drop Down Select Box', 'xprofile field type', 'buddypress' ); 2131 2132 $this->supports_options = true; 2133 2134 $this->set_format( '/^.+$/', 'replace' ); 2135 do_action( 'bp_xprofile_field_type_selectbox', $this ); 2136 } 2137 2138 /** 2139 * Output the edit field HTML for this field type. 2140 * 2141 * Must be used inside the {@link bp_profile_fields()} template loop. 2142 * 2143 * @param array $raw_properties Optional key/value array of {@link http://dev.w3.org/html5/markup/select.html permitted attributes} that you want to add. 2144 * @since BuddyPress (2.0.0) 2145 */ 2146 public function edit_field_html( array $raw_properties = array() ) { 2147 $user_id = bp_displayed_user_id(); 2148 2149 // user_id is a special optional parameter that we pass to {@link bp_the_profile_field_options()}. 2150 if ( isset( $raw_properties['user_id'] ) ) { 2151 $user_id = (int) $raw_properties['user_id']; 2152 unset( $raw_properties['user_id'] ); 2153 } 2154 2155 $html = $this->get_edit_field_html_elements( $raw_properties ); 2156 ?> 2157 <label for="<?php bp_the_profile_field_input_name(); ?>"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php 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 */ 2256 class BP_XProfile_Field_Type_Textarea extends BP_XProfile_Field_Type { 2257 2258 /** 2259 * Constructor for the textarea field type 2260 * 2261 * @since BuddyPress (2.0.0) 2262 */ 2263 public function __construct() { 2264 parent::__construct(); 2265 2266 $this->category = _x( 'Single Fields', 'xprofile field type category', 'buddypress' ); 2267 $this->name = _x( 'Multi-line Text Area', 'xprofile field type', 'buddypress' ); 2268 2269 $this->set_format( '/^.*$/m', 'replace' ); 2270 do_action( 'bp_xprofile_field_type_textarea', $this ); 2271 } 2272 2273 /** 2274 * Output the edit field HTML for this field type. 2275 * 2276 * Must be used inside the {@link bp_profile_fields()} template loop. 2277 * 2278 * @param array $raw_properties Optional key/value array of {@link http://dev.w3.org/html5/markup/textarea.html permitted attributes} that you want to add. 2279 * @since BuddyPress (2.0.0) 2280 */ 2281 public function edit_field_html( array $raw_properties = array() ) { 2282 2283 // user_id is a special optional parameter that certain other fields types pass to {@link bp_the_profile_field_options()}. 2284 if ( isset( $raw_properties['user_id'] ) ) { 2285 unset( $raw_properties['user_id'] ); 2286 } 2287 2288 $html = $this->get_edit_field_html_elements( array_merge( 2289 array( 2290 'cols' => 40, 2291 'rows' => 5, 2292 ), 2293 $raw_properties 2294 ) ); 2295 ?> 2296 <label for="<?php bp_the_profile_field_input_name(); ?>"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php 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 */ 2338 class BP_XProfile_Field_Type_Textbox extends BP_XProfile_Field_Type { 2339 2340 /** 2341 * Constructor for the textbox field type 2342 * 2343 * @since BuddyPress (2.0.0) 2344 */ 2345 public function __construct() { 2346 parent::__construct(); 2347 2348 $this->category = _x( 'Single Fields', 'xprofile field type category', 'buddypress' ); 2349 $this->name = _x( 'Text Box', 'xprofile field type', 'buddypress' ); 2350 2351 $this->set_format( '/^.*$/', 'replace' ); 2352 do_action( 'bp_xprofile_field_type_textbox', $this ); 2353 } 2354 2355 /** 2356 * Output the edit field HTML for this field type. 2357 * 2358 * Must be used inside the {@link bp_profile_fields()} template loop. 2359 * 2360 * @param array $raw_properties Optional key/value array of {@link http://dev.w3.org/html5/markup/input.text.html permitted attributes} that you want to add. 2361 * @since BuddyPress (2.0.0) 2362 */ 2363 public function edit_field_html( array $raw_properties = array() ) { 2364 2365 // user_id is a special optional parameter that certain other fields types pass to {@link bp_the_profile_field_options()}. 2366 if ( isset( $raw_properties['user_id'] ) ) { 2367 unset( $raw_properties['user_id'] ); 2368 } 2369 2370 $html = $this->get_edit_field_html_elements( array_merge( 2371 array( 2372 'type' => 'text', 2373 'value' => bp_get_the_profile_field_edit_value(), 2374 ), 2375 $raw_properties 2376 ) ); 2377 ?> 2378 <label for="<?php bp_the_profile_field_input_name(); ?>"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php 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 */ 2417 class BP_XProfile_Field_Type_Number extends BP_XProfile_Field_Type { 2418 2419 /** 2420 * Constructor for the number field type 2421 * 2422 * @since BuddyPress (2.0.0) 2423 */ 2424 public function __construct() { 2425 parent::__construct(); 2426 2427 $this->category = _x( 'Single Fields', 'xprofile field type category', 'buddypress' ); 2428 $this->name = _x( 'Number', 'xprofile field type', 'buddypress' ); 2429 2430 $this->set_format( '/^\d+$/', 'replace' ); 2431 do_action( 'bp_xprofile_field_type_number', $this ); 2432 } 2433 2434 /** 2435 * Output the edit field HTML for this field type. 2436 * 2437 * Must be used inside the {@link bp_profile_fields()} template loop. 2438 * 2439 * @param array $raw_properties Optional key/value array of {@link http://dev.w3.org/html5/markup/input.number.html permitted attributes} that you want to add. 2440 * @since BuddyPress (2.0.0) 2441 */ 2442 public function edit_field_html( array $raw_properties = array() ) { 2443 2444 // user_id is a special optional parameter that certain other fields types pass to {@link bp_the_profile_field_options()}. 2445 if ( isset( $raw_properties['user_id'] ) ) { 2446 unset( $raw_properties['user_id'] ); 2447 } 2448 2449 $html = $this->get_edit_field_html_elements( array_merge( 2450 array( 2451 'type' => 'number', 2452 'value' => bp_get_the_profile_field_edit_value(), 2453 ), 2454 $raw_properties 2455 ) ); 2456 ?> 2457 <label for="<?php bp_the_profile_field_input_name(); ?>"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php 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 */ 2496 abstract class BP_XProfile_Field_Type { 2497 2498 /** 2499 * @since BuddyPress (2.0.0) 2500 * @var array Field type validation regexes 2501 */ 2502 protected $validation_regex = array(); 2503 2504 /** 2505 * @since BuddyPress (2.0.0) 2506 * @var array Field type whitelisted values 2507 */ 2508 protected $validation_whitelist = array(); 2509 2510 /** 2511 * @since BuddyPress (2.0.0) 2512 * @var string The name of this field type 2513 */ 2514 public $name = ''; 2515 2516 /** 2517 * The name of the category that this field type should be grouped with. Used on the [Users > Profile Fields] screen in wp-admin. 2518 * 2519 * @since BuddyPress (2.0.0) 2520 * @var string 2521 */ 2522 public $category = ''; 2523 2524 /** 2525 * @since BuddyPress (2.0.0) 2526 * @var bool If this is set, allow BP to store null/empty values for this field type. 2527 */ 2528 public $accepts_null_value = false; 2529 2530 /** 2531 * If this is set, BP will set this field type's validation whitelist from the field's options (e.g checkbox, selectbox). 2532 * 2533 * @since BuddyPress (2.0.0) 2534 * @var bool Does this field support options? e.g. selectbox, radio buttons, etc. 2535 */ 2536 public $supports_options = false; 2537 2538 /** 2539 * @since BuddyPress (2.0.0) 2540 * @var bool Does this field type support multiple options being set as default values? e.g. multiselectbox, checkbox. 2541 */ 2542 public $supports_multiple_defaults = false; 2543 2544 /** 2545 * @since BuddyPress (2.0.0) 2546 * @var BP_XProfile_Field If this object is created by instantiating a {@link BP_XProfile_Field}, this is a reference back to that object. 2547 */ 2548 public $field_obj = null; 2549 2550 /** 2551 * Constructor 2552 * 2553 * @since BuddyPress (2.0.0) 2554 */ 2555 public function __construct() { 2556 do_action( 'bp_xprofile_field_type', $this ); 2557 } 2558 2559 /** 2560 * Set a regex that profile data will be asserted against. 2561 * 2562 * You can call this method multiple times to set multiple formats. When validation is performed, 2563 * it's successful as long as the new value matches any one of the registered formats. 2564 * 2565 * @param string $format Regex string 2566 * @param string $replace_format Optional; if 'replace', replaces the format instead of adding to it. Defaults to 'add'. 2567 * @return BP_XProfile_Field_Type 2568 * @since BuddyPress (2.0.0) 2569 */ 2570 public function set_format( $format, $replace_format = 'add' ) { 2571 2572 $format = apply_filters( 'bp_xprofile_field_type_set_format', $format, $replace_format, $this ); 2573 2574 if ( '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> Ξ </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
60 60 61 61 /*** Field Management *********************************************************/ 62 62 63 /** 64 * Get details of all xprofile field types. 65 * 66 * @return array Key/value pairs (field type => class name). 67 * @since BuddyPress (2.0.0) 68 */ 69 function bp_xprofile_get_field_types() { 70 $fields = array( 71 'checkbox' => 'BP_XProfile_Field_Type_Checkbox', 72 'datebox' => 'BP_XProfile_Field_Type_Datebox', 73 'multiselectbox' => 'BP_XProfile_Field_Type_Multiselectbox', 74 'number' => 'BP_XProfile_Field_Type_Number', 75 'radio' => 'BP_XProfile_Field_Type_Radiobutton', 76 'selectbox' => 'BP_XProfile_Field_Type_Selectbox', 77 'textarea' => 'BP_XProfile_Field_Type_Textarea', 78 'textbox' => 'BP_XProfile_Field_Type_Textbox', 79 ); 80 81 // If you've added a custom field type in a plugin, register it with this filter. 82 return apply_filters( 'bp_xprofile_get_field_types', $fields ); 83 } 84 85 /** 86 * Creates the specified field type object; used for validation and templating. 87 * 88 * @param string $type Type of profile field to create. See {@link bp_xprofile_get_field_types()} for default core values. 89 * @return object If field type unknown, returns BP_XProfile_Field_Type_Textarea. Otherwise returns an instance of the relevant child class of BP_XProfile_Field_Type. 90 * @since BuddyPress (2.0.0) 91 */ 92 function bp_xprofile_create_field_type( $type ) { 93 94 $field = bp_xprofile_get_field_types(); 95 $class = isset( $field[$type] ) ? $field[$type] : ''; 96 97 /** 98 * For backpat and to handle (missing) field types introduced by other plugins, fallback to 99 * textbox if a type is unknown. Textbox validation and display is intentionally low key. 100 */ 101 if ( $class && class_exists( $class ) ) { 102 return new $class; 103 } else { 104 return new BP_XProfile_Field_Type_Textbox; 105 } 106 } 107 63 108 function xprofile_insert_field( $args = '' ) { 64 109 global $bp; 65 110 … … 214 259 if ( $is_required && ( empty( $value ) || !is_array( $value ) && !strlen( trim( $value ) ) ) ) 215 260 return false; 216 261 217 $field = new BP_XProfile_Field( $field_id ); 262 $field = new BP_XProfile_Field( $field_id ); 263 $field_type_obj = bp_xprofile_create_field_type( BP_XProfile_Field::get_type( $field_id ) ); 218 264 219 // If the value is empty, then delete any field data that exists, unless the field is of a 220 // type where null values are semantically meaningful 221 if ( empty( $value ) && 'checkbox' != $field->type && 'multiselectbox' != $field->type ) { 265 // If the value is empty, then delete any field data that exists, unless the field is of a type where null values are semantically meaningful 266 if ( empty( $value ) && ! $field_type_obj->accepts_null_value ) { 222 267 xprofile_delete_field_data( $field_id, $user_id ); 223 268 return true; 224 269 } 225 270 226 $possible_values = array(); 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 } 227 275 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; 249 279 } 250 280 251 281 $field = new BP_XProfile_ProfileData(); -
bp-xprofile/bp-xprofile-loader.php
98 98 } 99 99 100 100 // Set the support field type ids 101 $this->field_types = apply_filters( 'xprofile_field_types', array( 102 'textbox', 103 'textarea', 104 'radio', 105 'checkbox', 106 'selectbox', 107 'multiselectbox', 108 'datebox' 109 ) ); 101 $this->field_types = apply_filters( 'xprofile_field_types', array_keys( bp_xprofile_get_field_types() ) ); 110 102 111 103 // Register the visibility levels. See bp_xprofile_get_visibility_levels() to filter 112 104 $this->visibility_levels = array( -
bp-xprofile/bp-xprofile-template.php
221 221 if ( $profile_template->current_field % 2 == 1 ) 222 222 $css_classes[] = 'alt'; 223 223 224 $css_classes[] = 'field_type_' . sanitize_title( $profile_template->field->type ); 224 225 $css_classes = apply_filters_ref_array( 'bp_field_css_classes', array( &$css_classes ) ); 225 226 226 227 return apply_filters( 'bp_get_field_css_class', ' class="' . implode( ' ', $css_classes ) . '"' ); … … 423 424 * 424 425 * @param array $args Specify type for datebox. Allowed 'day', 'month', 'year'. 425 426 */ 426 function bp_the_profile_field_options( $args = '') {427 function bp_the_profile_field_options( $args = array() ) { 427 428 echo bp_get_the_profile_field_options( $args ); 428 429 } 429 430 /** 430 431 * bp_get_the_profile_field_options() 431 432 * 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'. 434 434 * 435 435 * @package BuddyPress Xprofile 436 436 * @since BuddyPress (1.1) … … 446 446 * used when rendering options. Default: displayed user. 447 447 * } 448 448 */ 449 function bp_get_the_profile_field_options( $args = '') {449 function bp_get_the_profile_field_options( $args = array() ) { 450 450 global $field; 451 451 452 $ defaults =array(452 $args = bp_parse_args( $args, array( 453 453 'type' => false, 454 454 'user_id' => bp_displayed_user_id(), 455 ) ;455 ), 'profile_field_options_args' ); 456 456 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' ) ) { 464 462 $field_obj = new BP_XProfile_Field( $field->id ); 465 463 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} ) ) 468 466 $field_obj->{$field_prop} = $field_prop_value; 469 }470 467 } 471 468 472 469 $field = $field_obj; 473 470 } 474 471 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(); 476 476 477 // Setup some defaults478 $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 time498 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 match509 $allowed_options = xprofile_sanitize_data_value_before_save( $options[$k]->name, false, false );510 511 // First, check to see whether the user-entered value matches512 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 defaults517 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 time538 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 match548 $allowed_options = xprofile_sanitize_data_value_before_save( $options[$k]->name, false, false );549 550 // First, check to see whether the user-entered value matches551 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 defaults556 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 time571 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_save578 // filter, so we'll be sure to get a match579 $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 time596 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 values605 // match the option606 for ( $j = 0, $count_values = count( $option_values ); $j < $count_values; ++$j ) {607 608 // Run the allowed option name through the609 // before_save filter, so we'll be sure to get a match610 $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 available620 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 defaults632 $day = '';633 $month = '';634 $year = '';635 636 if ( !empty( $date ) ) {637 638 // If Unix timestamp639 if ( is_numeric( $date ) ) {640 $day = date( 'j', $date );641 $month = date( 'F', $date );642 $year = date( 'Y', $date );643 644 // If MySQL timestamp645 } else {646 $day = mysql2date( 'j', $date );647 $month = mysql2date( 'F', $date, false ); // Not localized, so that selected() works below648 $year = mysql2date( 'Y', $date );649 }650 }651 652 // Check for updated posted values, and errors preventing653 // 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 needed673 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 721 477 return $html; 722 478 } 723 479 … … 1014 770 1015 771 // Output the dropdown list 1016 772 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 */ 6 class BP_Tests_XProfile_Field_Type extends BP_UnitTestCase { 7 public function setUp() { 8 parent::setUp(); 9 } 10 11 public function tearDown() { 12 parent::tearDown(); 13 } 14 15 public function test_unregistered_field_type_returns_textbox() { 16 $field = bp_xprofile_create_field_type( 'fakeyfield' ); 17 $this->assertEquals( get_class( $field ), 'BP_XProfile_Field_Type_Textbox' ); 18 } 19 20 21 public function test_textbox_validate_empty_string() { 22 $field = bp_xprofile_create_field_type( 'textbox' ); 23 $this->assertTrue( $field->is_valid( '' ) ); 24 } 25 26 public function test_textbox_validate_string() { 27 $field = bp_xprofile_create_field_type( 'textbox' ); 28 $this->assertTrue( $field->is_valid( 'my 117th input string!' ) ); 29 } 30 31 public function test_textbox_validate_integer() { 32 $field = bp_xprofile_create_field_type( 'textbox' ); 33 $this->assertTrue( $field->is_valid( 123 ) ); 34 } 35 36 public function test_textbox_validate_whitelisted_string() { 37 $field = bp_xprofile_create_field_type( 'textbox' ); 38 39 $this->assertTrue( $field->is_valid( 'a string' ) ); 40 $this->assertFalse( $field->set_whitelist_values( 'pizza' )->is_valid( 'pasta' ) ); 41 $this->assertTrue( $field->is_valid( 'pizza' ) ); 42 } 43 44 45 public function test_multiselectbox_validate_whitelisted_array() { 46 $field = bp_xprofile_create_field_type( 'multiselectbox' ); 47 $field->set_whitelist_values( array( 'cheese', 'pepporoni' ) ); 48 49 $this->assertTrue( $field->is_valid( array( 'cheese', 'pepporoni' ) ) ); 50 $this->assertTrue( $field->is_valid( array( 'cheese' ) ) ); 51 $this->assertFalse( $field->is_valid( array( 'cheese', 'pepporoni', 'pinapple' ) ) ); 52 $this->assertFalse( $field->is_valid( array( 'pinapple' ) ) ); 53 } 54 55 public function test_multiselectbox_validate_null_value() { 56 $field = bp_xprofile_create_field_type( 'multiselectbox' ); 57 $field->set_whitelist_values( array( 'cheese', 'pepporoni' ) ); 58 59 $this->assertFalse( $field->is_valid( array( '' ) ) ); 60 $this->assertFalse( $field->is_valid( '' ) ); 61 $this->assertTrue( $field->is_valid( array() ) ); 62 } 63 64 65 public function test_datebox_do_not_validate_string() { 66 $field = bp_xprofile_create_field_type( 'datebox' ); 67 $this->assertFalse( $field->is_valid( 'datebox fields only accept strings in: Y-m-d 00:00:00' ) ); 68 $this->assertFalse( $field->is_valid( '' ) ); 69 } 70 71 public function test_datebox_do_not_validate_integer() { 72 $field = bp_xprofile_create_field_type( 'datebox' ); 73 $this->assertFalse( $field->is_valid( 221213 ) ); 74 } 75 76 public function test_datebox_validate_date() { 77 $field = bp_xprofile_create_field_type( 'datebox' ); 78 $this->assertTrue( $field->is_valid( '2013-12-22 00:00:00' ) ); 79 } 80 81 public function test_datebox_do_not_validate_date_with_timestamp() { 82 $field = bp_xprofile_create_field_type( 'datebox' ); 83 $this->assertFalse( $field->is_valid( '2013-12-22 19:11:30' ) ); 84 $this->assertFalse( $field->is_valid( '2013-12-22' ) ); 85 } 86 87 88 public function test_number_do_not_validate_string() { 89 $field = bp_xprofile_create_field_type( 'number' ); 90 $this->assertFalse( $field->is_valid( 'telephone fields only accept integers' ) ); 91 $this->assertFalse( $field->is_valid( '' ) ); 92 } 93 94 public function test_number_validate_integer() { 95 $field = bp_xprofile_create_field_type( 'number' ); 96 $this->assertTrue( $field->is_valid( 12345678901 ) ); 97 } 98 99 100 public function test_radiobutton_validate_whitelisted_array() { 101 $field = bp_xprofile_create_field_type( 'radio' ); 102 $field->set_whitelist_values( array( 'cheese', 'pepporoni' ) ); 103 104 $this->assertTrue( $field->is_valid( array( 'cheese', 'pepporoni' ) ) ); 105 $this->assertTrue( $field->is_valid( array( 'cheese' ) ) ); 106 $this->assertFalse( $field->is_valid( array( 'cheese', 'pepporoni', 'pinapple' ) ) ); 107 $this->assertFalse( $field->is_valid( array( 'pinapple' ) ) ); 108 $this->assertFalse( $field->is_valid( '' ) ); 109 } 110 111 public function test_radiobutton_do_not_validate_empty_items_in_whitelist() { 112 $field = bp_xprofile_create_field_type( 'radio' ); 113 $field->set_whitelist_values( array( '' ) ); 114 115 $this->assertFalse( $field->is_valid( array( '' ) ) ); 116 } 117 118 119 public function test_checkbox_validate_whitelisted_array() { 120 $field = bp_xprofile_create_field_type( 'checkbox' ); 121 $field->set_whitelist_values( array( 'cheese', 'pepporoni' ) ); 122 123 $this->assertTrue( $field->is_valid( array( 'cheese', 'pepporoni' ) ) ); 124 $this->assertTrue( $field->is_valid( array( 'cheese' ) ) ); 125 $this->assertFalse( $field->is_valid( array( 'cheese', 'pepporoni', 'pinapple' ) ) ); 126 $this->assertFalse( $field->is_valid( array( 'pinapple' ) ) ); 127 $this->assertFalse( $field->is_valid( '' ) ); 128 } 129 130 public function test_checkbox_validate_null_value() { 131 $field = bp_xprofile_create_field_type( 'checkbox' ); 132 $field->set_whitelist_values( array( 'cheese', 'pepporoni' ) ); 133 134 $this->assertFalse( $field->is_valid( array( '' ) ) ); 135 $this->assertFalse( $field->is_valid( '' ) ); 136 $this->assertTrue( $field->is_valid( array() ) ); 137 } 138 }