Skip to content

Instantly share code, notes, and snippets.

@boonebgorges
Created Jul 14, 2015
Embed
What would you like to do?
"other" field for bp-xprofile
/**
* Add an 'Other' type to xprofile fields
*
* @link https://buddypress.trac.wordpress.org/ticket/3775
* @link http://redmine.gc.cuny.edu/issues/1199
*/
class CAC_Xprofile_Other {
function __construct() {
add_action( 'xprofile_field_additional_options', array( &$this, 'render_admin' ) );
add_action( 'xprofile_fields_saved_field', array( &$this, 'save_admin_field' ) );
add_action( 'bp_get_the_profile_field_options_checkbox', array( &$this, 'render_field' ), 10, 5 );
add_action( 'xprofile_data_after_save', array( &$this, 'save_field_data' ) );
// Call early to beat race condition for auto-links
add_action( 'bp_get_the_profile_field_value', array( &$this, 'render_public_field' ), 5, 3 );
// Have to fudge to make searches work
add_filter( 'bp_core_get_paged_users_sql', array( $this, 'users_sql_filter' ), 100, 2 );
add_filter( 'bp_core_get_total_users_sql', array( $this, 'users_sql_filter' ), 100, 2 );
}
function render_admin() {
$field_id = isset( $_GET['field_id'] ) ? (int)$_GET['field_id'] : NULL;
$other_toggle = 'yes' == bp_xprofile_get_meta( $field_id, 'field', 'cac_other_field' );
?>
<div id="titlediv">
<h3>'Other' field</h3>
<label for="cac-other-field">Add an "Other" option at the end of this list (a checkbox/radio button + a text field)?</label><br />
<input type="radio" name="cac-other-field" value="yes" <?php checked( $other_toggle, true ) ?>/> Yes<br />
<input type="radio" name="cac-other-field" value="no" <?php checked( !$other_toggle, true ) ?>/> No
</div>
<?php
}
function save_admin_field( $field ) {
if ( isset( $_POST['cac-other-field'] ) ) {
// When creating a new field, no field_id will have been set yet. We'll
// look it up based on the $field object passed to the hook
if ( empty( $this->field_id ) ) {
$this->field_id = BP_XProfile_Field::get_id_from_name( $field->name );
}
$data = 'yes' == $_POST['cac-other-field'] ? 'yes' : 'no';
bp_xprofile_update_field_meta( $this->field_id, 'cac_other_field', $data );
}
}
function render_field() {
$field_id = func_get_arg( 2 );
$field = wp_cache_get( 'xprofile_parent_field_' . $field_id, 'bp' );
if ( !$field ) {
$field = new BP_XProfile_Field( $field_id );
wp_cache_set( 'xprofile_parent_field_' . $field_id, $field, 'bp' );
}
$siblings = wp_cache_get( 'xprofile_siblings_' . $field_id, 'bp' );
if ( !$siblings ) {
$siblings = $field->get_children();
wp_cache_set( 'xprofile_siblings_' . $field_id, $siblings, 'bp' );
}
// Only continue if this is the last in the list
$position = func_get_arg( 4 ) + 1;
if ( $position != count( $siblings ) ) {
return func_get_arg( 0 );
}
// Only continue if the Other field is enabled for this item
if ( 'yes' != bp_xprofile_get_meta( $field_id, 'field', 'cac_other_field' ) ) {
return func_get_arg( 0 );
}
$current_value = new BP_XProfile_ProfileData( $field_id, bp_displayed_user_id() );
if ( isset( $current_value->id ) ) {
$is_checked = 'yes' == bp_xprofile_get_meta( $current_value->id, 'data', 'cac_other_field' );
$other_text = bp_xprofile_get_meta( $current_value->id, 'data', 'cac_other_field_text' );
} else {
$is_checked = false;
$other_text = '';
}
/*
$field_name = 'field_' . $field_id . '_other';
if ( 'checkbox' == $field->type ) {
$field_name .= '[]';
}
*/
$checked = $is_checked ? ' checked="checked" ' : '';
$html = func_get_arg( 0 ) . '<label><input type="' . $field->type . '" name="field_' . $field_id . '[other]" id="field_' . $field_id . '_other" value="cac_other_value"' . $checked . '> Other </label> <input class="other-text" type="text" name="field_' . $field_id . '_other_text" value="' . esc_attr( $other_text ) . '" />';
return $html;
}
function save_field_data( $fielddata ) {
// Groan
if ( 'yes' != bp_xprofile_get_meta( $fielddata->field_id, 'field', 'cac_other_field' ) ) {
return;
}
$fid = $fielddata->field_id;
$current_value = new BP_XProfile_ProfileData( $fid, bp_displayed_user_id() );
if ( isset( $_POST['field_' . $fid] ) && is_array( $_POST['field_' . $fid] ) && !empty( $current_value->id ) ) {
if( !empty( $_POST['field_' . $fid]['other'] ) ) {
if ( isset( $_POST['field_' . $fid . '_other_text'] ) ) {
bp_xprofile_update_meta( $current_value->id, 'data', 'cac_other_field_text', $_POST['field_' . $fid . '_other_text'] );
bp_xprofile_update_meta( $current_value->id, 'data', 'cac_other_field', 'yes' );
}
} else {
bp_xprofile_update_meta( $current_value->id, 'data', 'cac_other_field', 'no' );
}
}
}
function render_public_field( $html, $type, $fid ) {
if ( in_array( $type, array( 'textbox', 'textarea' ) ) ) {
return $html;
}
$current_value = new BP_XProfile_ProfileData( $fid, bp_displayed_user_id() );
$is_checked = 'yes' == bp_xprofile_get_meta( $current_value->id, 'data', 'cac_other_field' );
if ( $is_checked ) {
$other_text = bp_xprofile_get_meta( $current_value->id, 'data', 'cac_other_field_text' );
if ( $other_text ) {
$html .= ', ' . $other_text;
}
}
return $html;
}
function users_sql_filter( $sql, $sql_array ) {
global $bp, $wpdb;
// If there's a search going on, and this is a directory, do it
if ( bp_is_members_component() && bp_is_directory() && isset( $_GET['s'] ) ) {
// Get a list of matching users
$matching_users = $wpdb->get_col( $wpdb->prepare( "SELECT d.user_id FROM {$bp->profile->table_name_data} d LEFT JOIN {$bp->profile->table_name_meta} m ON (d.id = m.object_id) WHERE m.object_type = 'data' AND m.meta_key = 'cac_other_field_text' AND m.meta_value LIKE '%%" . like_escape( $_GET['s'] ) . "%%'" ) );
if ( !empty( $matching_users ) ) {
$uids = implode( ',', wp_parse_id_list( $matching_users ) );
$sql = preg_replace( '/(spd\.value LIKE \'.+\')/', '($1 OR u.ID IN (' . $uids . '))', $sql );
}
}
return $sql;
}
}
new CAC_Xprofile_Other();
@rosemalfoy
Copy link

rosemalfoy commented Feb 1, 2018

I get this error when I enter something in the Others textbox & save changes.
'There was a problem updating some of your profile information. Please try again.'

What am I doing wrong?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment