Skip to:
Content

Ticket #6789: 6789.06.patch

File 6789.06.patch, 22.5 KB (added by boonebgorges, 5 months ago)
  • src/bp-xprofile/bp-xprofile-filters.php

    diff --git a/src/bp-xprofile/bp-xprofile-filters.php b/src/bp-xprofile/bp-xprofile-filters.php
    index dd3f7c567..33997a130 100644
    a b function xprofile_filter_kses( $content, $data_obj = null ) { 
    154154 * Safely runs profile field data through kses and force_balance_tags.
    155155 *
    156156 * @since 1.2.6
     157 * @since 3.0.0 The `$field_value` parameter accepts an array.
    157158 *
    158  * @param string      $field_value Field value being santized.
    159  * @param int         $field_id    Field ID being sanitized.
    160  * @param bool        $reserialize Whether to reserialize arrays before returning. Defaults to true.
    161  * @param object|null $data_obj    The BP_XProfile_ProfileData object.
     159 * @param string       $field_value Field value being santized.
     160 * @param int          $field_id    Field ID being sanitized.
     161 * @param bool         $reserialize Whether to reserialize arrays before returning. Defaults to true.
     162 * @param object|null  $data_obj    The BP_XProfile_ProfileData object.
     163 * @return string|array
    162164 * @return string
    163165 */
    164166function xprofile_sanitize_data_value_before_save( $field_value, $field_id = 0, $reserialize = true, $data_obj = null ) {
    function xprofile_sanitize_data_value_before_save( $field_value, $field_id = 0, 
    176178        // Value might be a serialized array of options.
    177179        $field_value = maybe_unserialize( $field_value );
    178180
     181        // Return if empty. Special-case support for integer 0 for the number field type.
     182        if ( empty( $field_value ) && ! is_integer( $field_value ) && $field_value !== '0' ) {
     183                return $field_value;
     184        }
     185
    179186        // Sanitize single field value.
    180         if ( ! is_array( $field_value ) ) {
     187        if ( ! $data_obj || ! bp_xprofile_field_supports_multiple_values( $data_obj->field_id ) ) {
    181188                $kses_field_value     = xprofile_filter_kses( $field_value, $data_obj );
    182189                $filtered_field_value = wp_rel_nofollow( force_balance_tags( $kses_field_value ) );
    183190
    function xprofile_sanitize_data_value_before_save( $field_value, $field_id = 0, 
    185192                 * Filters the kses-filtered data before saving to database.
    186193                 *
    187194                 * @since 1.5.0
     195                 * @since 3.0.0 The `$filtered_field_value` accepts an array.
    188196                 *
    189                  * @param string                  $filtered_field_value The filtered value.
     197                 * @param string|array            $filtered_field_value The filtered value.
    190198                 * @param string                  $field_value          The original value before filtering.
    191199                 * @param BP_XProfile_ProfileData $data_obj             The BP_XProfile_ProfileData object.
    192200                 */
    193201                $filtered_field_value = apply_filters( 'xprofile_filtered_data_value_before_save', $filtered_field_value, $field_value, $data_obj );
    194202
     203                if ( ! empty( $reserialize ) ) {
     204                        $filtered_field_value = maybe_serialize( $filtered_field_value );
     205                }
     206
    195207        // Sanitize multiple individual option values.
    196208        } else {
    197209                $filtered_values = array();
    198210                foreach ( (array) $field_value as $value ) {
    199                         $kses_field_value = xprofile_filter_kses( $value, $data_obj );
    200                         $filtered_value   = wp_rel_nofollow( force_balance_tags( $kses_field_value ) );
     211                        $unserialized_value = maybe_unserialize( $value );
     212                        $kses_field_value   = xprofile_filter_kses( $unserialized_value, $data_obj );
     213                        $filtered_value     = wp_rel_nofollow( force_balance_tags( $kses_field_value ) );
    201214
    202215                        /** This filter is documented in bp-xprofile/bp-xprofile-filters.php */
    203216                        $filtered_values[] = apply_filters( 'xprofile_filtered_data_value_before_save', $filtered_value, $value, $data_obj );
    204217                }
    205218
    206                 if ( !empty( $reserialize ) ) {
    207                         $filtered_field_value = serialize( $filtered_values );
     219                if ( ! empty( $reserialize ) ) {
     220                        $filtered_field_value = array_map( 'maybe_serialize', $filtered_values );
    208221                } else {
    209222                        $filtered_field_value = $filtered_values;
    210223                }
  • src/bp-xprofile/bp-xprofile-functions.php

    diff --git a/src/bp-xprofile/bp-xprofile-functions.php b/src/bp-xprofile/bp-xprofile-functions.php
    index 337d2cd79..c34625f01 100644
    a b function xprofile_get_field_data( $field, $user_id = 0, $multi_format = 'array' 
    362362
    363363        $values = maybe_unserialize( BP_XProfile_ProfileData::get_value_byid( $field_id, $user_id ) );
    364364
    365         if ( is_array( $values ) ) {
     365        // Consider multiple values.
     366        if ( bp_xprofile_field_supports_multiple_values( $field_id ) ) {
     367                $values = array_map( 'maybe_unserialize', $values );
    366368                $data = array();
    367369                foreach( (array) $values as $value ) {
    368370
    function xprofile_set_field_data( $field, $user_id, $value, $is_required = false 
    467469        $field->user_id  = $user_id;
    468470
    469471        // Gets un/reserialized via xprofile_sanitize_data_value_before_save()
    470         $field->value    = maybe_serialize( $value );
     472        if ( bp_xprofile_field_supports_multiple_values( $field_id ) ) {
     473                $field->value = array_map( 'maybe_serialize', $value );
     474        } else {
     475                $field->value = maybe_serialize( $value );
     476        }
    471477
    472478        return $field->save();
    473479}
    function xprofile_get_random_profile_data( $user_id, $exclude_fullname = true ) 
    641647 * Formats a profile field according to its type. [ TODO: Should really be moved to filters ]
    642648 *
    643649 * @since 1.0.0
     650 * @since 3.0.0 The `$field_value` parameter can be an array.
    644651 *
    645  * @param string $field_type  The type of field: datebox, selectbox, textbox etc.
    646  * @param string $field_value The actual value.
     652 * @param string       $field_type  The type of field: datebox, selectbox, textbox etc.
     653 * @param string|array $field_value The actual value.
    647654 * @return string|bool The formatted value, or false if value is empty.
    648655 */
    649656function xprofile_format_profile_field( $field_type, $field_value ) {
    function bp_xprofile_is_richtext_enabled_for_field( $field_id = null ) { 
    11461153        return apply_filters( 'bp_xprofile_is_richtext_enabled_for_field', $enabled, $field_id );
    11471154}
    11481155
     1156/**
     1157 * Does this profile field support multiple values?
     1158 *
     1159 * @since 3.0.0
     1160 *
     1161 * @param int|null $field_id Optional. Default current field ID.
     1162 * @return bool              Whether the field supports multiple values
     1163 */
     1164function bp_xprofile_field_supports_multiple_values( $field_id = null ) {
     1165        if ( ! $field_id ) {
     1166                $field_id = bp_get_the_profile_field_id();
     1167        }
     1168
     1169        $field = xprofile_get_field( $field_id, null, false );
     1170
     1171        $supports = false;
     1172        if ( $field instanceof BP_XProfile_Field ) {
     1173                $supports = (bool) $field->type_obj->supports_multiple_values;
     1174        }
     1175
     1176        /**
     1177         * Filters whether the given field supports multiple values.
     1178         *
     1179         * @since 3.0.0
     1180         *
     1181         * @param bool $supports True if the field supports multiple values, otherwise false.
     1182         * @param int  $field_id ID of the field.
     1183         */
     1184        return (bool) apply_filters( 'bp_xprofile_field_supports_multiple_values', $supports, $field_id );
     1185}
     1186
    11491187/**
    11501188 * Get visibility levels out of the $bp global.
    11511189 *
  • src/bp-xprofile/bp-xprofile-template.php

    diff --git a/src/bp-xprofile/bp-xprofile-template.php b/src/bp-xprofile/bp-xprofile-template.php
    index afe5162ec..e4f8ad277 100644
    a b function bp_the_profile_field_visibility_level_label() { 
    903903 * comma-separated string.
    904904 *
    905905 * @since 1.0.0
     906 * @since 3.0.0 The `$value` parameter can be an array.
    906907 *
    907  * @param string $value Content to maybe unserialize.
     908 * @param string|array $value Content to maybe unserialize.
    908909 * @return string
    909910 */
    910911function bp_unserialize_profile_field( $value ) {
    911         if ( is_serialized($value) ) {
    912                 $field_value = @unserialize($value);
     912        if ( is_serialized( $value ) || is_array( $value ) ) {
     913                $field_value = maybe_unserialize( $value );
    913914                $field_value = implode( ', ', $field_value );
    914915                return $field_value;
    915916        }
  • src/bp-xprofile/classes/class-bp-xprofile-field-type-checkbox.php

    diff --git a/src/bp-xprofile/classes/class-bp-xprofile-field-type-checkbox.php b/src/bp-xprofile/classes/class-bp-xprofile-field-type-checkbox.php
    index f3717d3dc..895e07082 100644
    a b class BP_XProfile_Field_Type_Checkbox extends BP_XProfile_Field_Type { 
    2828                $this->category = _x( 'Multi Fields', 'xprofile field type category', 'buddypress' );
    2929                $this->name     = _x( 'Checkboxes', 'xprofile field type', 'buddypress' );
    3030
     31                $this->supports_multiple_values   = true;
    3132                $this->supports_multiple_defaults = true;
    3233                $this->accepts_null_value         = true;
    3334                $this->supports_options           = true;
  • src/bp-xprofile/classes/class-bp-xprofile-field-type-multiselectbox.php

    diff --git a/src/bp-xprofile/classes/class-bp-xprofile-field-type-multiselectbox.php b/src/bp-xprofile/classes/class-bp-xprofile-field-type-multiselectbox.php
    index d56b25be4..718b79d2a 100644
    a b class BP_XProfile_Field_Type_Multiselectbox extends BP_XProfile_Field_Type { 
    2828                $this->category = _x( 'Multi Fields', 'xprofile field type category', 'buddypress' );
    2929                $this->name     = _x( 'Multi Select Box', 'xprofile field type', 'buddypress' );
    3030
     31                $this->supports_multiple_values   = true;
    3132                $this->supports_multiple_defaults = true;
    3233                $this->accepts_null_value         = true;
    3334                $this->supports_options           = true;
  • src/bp-xprofile/classes/class-bp-xprofile-field-type.php

    diff --git a/src/bp-xprofile/classes/class-bp-xprofile-field-type.php b/src/bp-xprofile/classes/class-bp-xprofile-field-type.php
    index 65a970c68..66e451df4 100644
    a b abstract class BP_XProfile_Field_Type { 
    6565         */
    6666        public $supports_options = false;
    6767
     68        /**
     69         * If allowed to store multiple values.
     70         *
     71         * @since 3.0.0
     72         * @var bool Does this field support multiple values? e.g. multiselectbox, checkbox.
     73         */
     74        public $supports_multiple_values = false;
     75
    6876        /**
    6977         * If allowed to support multiple options as default.
    7078         *
  • src/bp-xprofile/classes/class-bp-xprofile-profiledata.php

    diff --git a/src/bp-xprofile/classes/class-bp-xprofile-profiledata.php b/src/bp-xprofile/classes/class-bp-xprofile-profiledata.php
    index 62603e7c0..c02201134 100644
    a b class BP_XProfile_ProfileData { 
    8989                        $bp = buddypress();
    9090
    9191                        $sql         = $wpdb->prepare( "SELECT * FROM {$bp->profile->table_name_data} WHERE field_id = %d AND user_id = %d", $field_id, $user_id );
    92                         $profiledata = $wpdb->get_row( $sql );
     92                        $profiledata = $wpdb->get_results( $sql );
    9393
    9494                        if ( $profiledata ) {
     95
     96                                // If the field supports multiple values, an array should be returned.
     97                                if ( bp_xprofile_field_supports_multiple_values( $profiledata[0]->field_id ) ) {
     98                                        $profiledata[0]->value = wp_list_pluck( $profiledata, 'value' );
     99
     100                                        // Parse empty list
     101                                        if ( array() === maybe_unserialize( $profiledata[0]->value ) ) {
     102                                                $profiledata[0]->value = array();
     103                                        }
     104                                }
     105
     106                                // Get the first row
     107                                $profiledata = $profiledata[0];
    95108                                wp_cache_set( $cache_key, $profiledata, 'bp_xprofile_data' );
    96109                        }
    97110                }
    class BP_XProfile_ProfileData { 
    100113                        $this->id           = (int) $profiledata->id;
    101114                        $this->user_id      = (int) $profiledata->user_id;
    102115                        $this->field_id     = (int) $profiledata->field_id;
    103                         $this->value        = stripslashes( $profiledata->value );
     116                        $this->value        = is_array( $profiledata->value ) ? array_map( 'stripslashes', $profiledata->value ) : stripslashes( $profiledata->value );
    104117                        $this->last_updated = $profiledata->last_updated;
    105118
    106119                } else {
    class BP_XProfile_ProfileData { 
    184197
    185198                $bp = buddypress();
    186199
    187                 $this->user_id      = apply_filters( 'xprofile_data_user_id_before_save',      $this->user_id,         $this->id );
    188                 $this->field_id     = apply_filters( 'xprofile_data_field_id_before_save',     $this->field_id,        $this->id );
    189                 $this->value        = apply_filters( 'xprofile_data_value_before_save',        $this->value,           $this->id, true, $this );
     200                /**
     201                 * Filters the data's user ID before saving to the database.
     202                 *
     203                 * @since 1.0.0
     204                 *
     205                 * @param int $user_id The user ID.
     206                 * @param int $data_id The field data ID.
     207                 */
     208                $this->user_id = apply_filters( 'xprofile_data_user_id_before_save', $this->user_id, $this->id );
     209
     210                /**
     211                 * Filters the data's field ID before saving to the database.
     212                 *
     213                 * @since 1.0.0
     214                 *
     215                 * @param int $field_id The field ID.
     216                 * @param int $data_id  The field data ID.
     217                 */
     218                $this->field_id = apply_filters( 'xprofile_data_field_id_before_save', $this->field_id, $this->id );
     219
     220                /**
     221                 * Filters the data's value before saving to the database.
     222                 *
     223                 * @since 1.0.0
     224                 * @since 2.1.0 Added `$reserialize` and `$this` parameters.
     225                 *
     226                 * @param string                  $field_value The field value.
     227                 * @param int                     $data_id     The field data ID.
     228                 * @param bool                    $reserialize Whether to reserialize arrays before returning. Defaults to true.
     229                 * @param BP_XProfile_ProfileData $this        Current instance of the profile data being saved.
     230                 */
     231                $this->value = apply_filters( 'xprofile_data_value_before_save', $this->value, $this->id, true, $this );
     232
     233                /**
     234                 * Filters the data's last updated timestamp before saving to the database.
     235                 *
     236                 * @since 1.0.0
     237                 *
     238                 * @param int $last_updated The last updated timestamp.
     239                 * @param int $data_id      The field data ID.
     240                 */
    190241                $this->last_updated = apply_filters( 'xprofile_data_last_updated_before_save', bp_core_current_time(), $this->id );
    191242
    192243                /**
    class BP_XProfile_ProfileData { 
    201252                do_action_ref_array( 'xprofile_data_before_save', array( $this ) );
    202253
    203254                if ( $this->is_valid_field() ) {
    204                         if ( $this->exists() && strlen( trim( $this->value ) ) ) {
     255
     256                        // Special-case support for integer 0 for the number field type
     257                        $value_is_empty = empty( $this->value ) && ! is_integer( $this->value ) && '0' !== $this->value;
     258
     259                        // Store as multiple values
     260                        if ( $this->exists() && bp_xprofile_field_supports_multiple_values( $this->field_id ) ) {
     261
     262                                // Delete previous rows.
     263                                $this->delete();
     264
     265                                // Store empty list as serialized array
     266                                if ( empty( $this->value ) ) {
     267                                        $this->value = array( serialize( array() ) );
     268                                }
     269
     270                                // Store each value in a separate row
     271                                foreach ( array_values( (array) $this->value ) as $k => $value ) {
     272                                        $result = $wpdb->query( $wpdb->prepare("INSERT INTO {$bp->profile->table_name_data} (user_id, field_id, value, last_updated) VALUES (%d, %d, %s, %s)", $this->user_id, $this->field_id, $value, $this->last_updated ) );
     273
     274                                        // Use the first inserted id as the new data identifier
     275                                        if ( 0 === $k ) {
     276                                                $this->id = $wpdb->insert_id;
     277                                        }
     278                                }
     279
     280                        // Store as single value
     281                        } elseif ( $this->exists() && ! $value_is_empty ) {
    205282                                $result   = $wpdb->query( $wpdb->prepare( "UPDATE {$bp->profile->table_name_data} SET value = %s, last_updated = %s WHERE user_id = %d AND field_id = %d", $this->value, $this->last_updated, $this->user_id, $this->field_id ) );
    206283
    207                         } elseif ( $this->exists() && empty( $this->value ) ) {
    208                                 // Data removed, delete the entry.
     284                        // Data removed, delete the entry.
     285                        } elseif ( $this->exists() && $value_is_empty ) {
    209286                                $result   = $this->delete();
    210287
    211                         } else {
     288                        } elseif ( ! $value_is_empty ) {
    212289                                $result   = $wpdb->query( $wpdb->prepare("INSERT INTO {$bp->profile->table_name_data} (user_id, field_id, value, last_updated) VALUES (%d, %d, %s, %s)", $this->user_id, $this->field_id, $this->value, $this->last_updated ) );
    213290                                $this->id = $wpdb->insert_id;
    214291                        }
    class BP_XProfile_ProfileData { 
    299376                        // Rekey.
    300377                        $queried_data = array();
    301378                        foreach ( $uncached_data as $ud ) {
    302                                 $d               = new stdClass;
    303                                 $d->id           = $ud->id;
    304                                 $d->user_id      = $ud->user_id;
    305                                 $d->field_id     = $ud->field_id;
    306                                 $d->value        = $ud->value;
    307                                 $d->last_updated = $ud->last_updated;
    308 
    309                                 $queried_data[ $ud->field_id ] = $d;
     379
     380                                // Set initial field data
     381                                if ( ! isset( $queried_data[ $ud->field_id ] ) ) {
     382                                        $d               = new stdClass;
     383                                        $d->id           = $ud->id;
     384                                        $d->user_id      = $ud->user_id;
     385                                        $d->field_id     = $ud->field_id;
     386                                        $d->last_updated = $ud->last_updated;
     387
     388                                        // Collect multiple values in array
     389                                        // TODO: no stripslashing here? See ::populate()
     390                                        if ( bp_xprofile_field_supports_multiple_values( $ud->field_id ) ) {
     391                                                $d->value = ( array() === maybe_unserialize( $ud->value ) ) ? array() : array( $ud->value );
     392                                        } else {
     393                                                $d->value = $ud->value;
     394                                        }
     395
     396                                        $queried_data[ $ud->field_id ] = $d;
     397
     398                                // Collect multiple values per field
     399                                } elseif ( bp_xprofile_field_supports_multiple_values( $ud->field_id ) ) {
     400                                        // TODO: no stripslashing here? See ::populate()
     401                                        $queried_data[ $ud->field_id ]->value[] = $ud->value;
     402                                }
    310403                        }
    311404
    312405                        // Set caches.
    class BP_XProfile_ProfileData { 
    325418                                        $d->id           = '';
    326419                                        $d->user_id      = $user_id;
    327420                                        $d->field_id     = $field_id;
    328                                         $d->value        = '';
     421                                        $d->value        = bp_xprofile_field_supports_multiple_values( $field_id ) ? array() : '';
    329422                                        $d->last_updated = '';
    330423
    331424                                        wp_cache_set( $cache_key, $d, 'bp_xprofile_data' );
    class BP_XProfile_ProfileData { 
    405498         * Get the user's field data id by the id of the xprofile field.
    406499         *
    407500         * @since 1.6.0
     501         * @since 3.0.0 Returns the first/main data id in case of multiple values.
    408502         *
    409503         * @param int $field_id Field ID being queried for.
    410504         * @param int $user_id  User ID associated with field.
    class BP_XProfile_ProfileData { 
    471565                        $bp = buddypress();
    472566                        $uncached_ids_sql = implode( ',', $uncached_ids );
    473567                        $queried_data = $wpdb->get_results( $wpdb->prepare( "SELECT id, user_id, field_id, value, last_updated FROM {$bp->profile->table_name_data} WHERE field_id = %d AND user_id IN ({$uncached_ids_sql})", $field_id ) );
     568                        $multiple = bp_xprofile_field_supports_multiple_values( $field_id );
    474569
    475570                        // Rekey.
    476571                        $qd = array();
    477572                        foreach ( $queried_data as $data ) {
    478                                 $qd[ $data->user_id ] = $data;
     573
     574                                // Set initial user data
     575                                if ( ! isset( $qd[ $data->user_id ] ) ) {
     576
     577                                        // Collect multiple values in array
     578                                        if ( $multiple ) {
     579                                                // TODO: no stripslashing here? See ::populate().
     580                                                $data->value = ( array() === maybe_unserialize( $data->value ) ) ? array() : array( $data->value );
     581                                        }
     582
     583                                        $qd[ $data->user_id ] = $data;
     584
     585                                // Collect multiple values per field
     586                                } elseif ( $multiple ) {
     587                                        // TODO: no stripslashing here? See ::populate().
     588                                        $qd[ $data->user_id ]->value[] = $data->value;
     589                                }
    479590                        }
    480591
    481592                        foreach ( $uncached_ids as $id ) {
    class BP_XProfile_ProfileData { 
    490601                                        $d->id           = '';
    491602                                        $d->user_id      = $id;
    492603                                        $d->field_id     = $field_id;
    493                                         $d->value        = '';
     604                                        $d->value        = $multiple ? array() : '';
    494605                                        $d->last_updated = '';
    495606                                }
    496607
    class BP_XProfile_ProfileData { 
    566677                        $field_sql .= $wpdb->prepare( "AND f.name = %s", $fields );
    567678                }
    568679
    569                 $sql    = $wpdb->prepare( "SELECT d.value, f.name FROM {$bp->profile->table_name_data} d, {$bp->profile->table_name_fields} f WHERE d.field_id = f.id AND d.user_id = %d AND f.parent_id = 0 $field_sql", $user_id );
     680                $sql    = $wpdb->prepare( "SELECT d.value, f.name, f.id FROM {$bp->profile->table_name_data} d, {$bp->profile->table_name_fields} f WHERE d.field_id = f.id AND d.user_id = %d AND f.parent_id = 0 $field_sql", $user_id );
    570681                $values = $wpdb->get_results( $sql );
    571682
     683                // TODO: checking for empty result/WP_Error, but not in other methods?
    572684                if ( empty( $values ) || is_wp_error( $values ) ) {
    573685                        return false;
    574686                }
    class BP_XProfile_ProfileData { 
    579691                        for ( $i = 0, $count = count( $values ); $i < $count; ++$i ) {
    580692                                for ( $j = 0; $j < count( $fields ); $j++ ) {
    581693                                        if ( $values[$i]->name == $fields[$j] ) {
    582                                                 $new_values[$fields[$j]] = $values[$i]->value;
     694                                                $multiple = bp_xprofile_field_supports_multiple_values( $values[$i]->id );
     695
     696                                                // TODO: no stripslashing here? See ::populate()
     697                                                if ( ! isset( $new_values[ $fields[$j] ] ) ) {
     698                                                        if ( $multiple ) {
     699                                                                $new_values[$fields[$j]] = ( array() === $values[$i]->value ) ? array() : array( $values[$i]->value );
     700                                                        } else {
     701                                                                $new_values[$fields[$j]] = $values[$i]->value;
     702                                                        }
     703                                                } elseif ( $multiple ) {
     704                                                        $new_values[$fields[$j]][] = $values[$i]->value;
     705                                                }
    583706                                        } elseif ( !array_key_exists( $fields[$j], $new_values ) ) {
    584707                                                $new_values[$fields[$j]] = NULL;
    585708                                        }
    586709                                }
    587710                        }
    588711                } else {
    589                         $new_values = $values[0]->value;
     712
     713                        // Collect multiple values in array
     714                        // TODO: no stripslashing here? See ::populate()
     715                        if ( bp_xprofile_field_supports_multiple_values( $values[0]->id ) ) {
     716                                $new_values = wp_list_pluck( $values, 'value' );
     717
     718                                // Parse empty list
     719                                if ( array() === maybe_unserialize( $new_values[0] ) ) {
     720                                        $new_values = array();
     721                                }
     722                        } else {
     723                                $new_values = $values[0]->value;
     724                        }
    590725                }
    591726
    592727                return $new_values;
    class BP_XProfile_ProfileData { 
    651786         *
    652787         * @since 1.0.0
    653788         *
    654          * @param int    $user_id          User ID to query for.
    655          * @param string $exclude_fullname SQL portion used to exclude by field ID.
     789         * @param int  $user_id          User ID to query for.
     790         * @param bool $exclude_fullname Optional. Whether to exclude the fullname field. Defaults to false.
    656791         * @return array|null|object
    657792         */
    658         public static function get_random( $user_id, $exclude_fullname ) {
     793        public static function get_random( $user_id, $exclude_fullname = false ) {
    659794                global $wpdb;
    660795
    661796                $exclude_sql = ! empty( $exclude_fullname ) ? ' AND pf.id != 1' : '';
    662797
    663798                $bp = buddypress();
    664799
    665                 return $wpdb->get_results( $wpdb->prepare( "SELECT pf.type, pf.name, pd.value FROM {$bp->profile->table_name_data} pd INNER JOIN {$bp->profile->table_name_fields} pf ON pd.field_id = pf.id AND pd.user_id = %d {$exclude_sql} ORDER BY RAND() LIMIT 1", $user_id ) );
     800                $rand_sql = "SELECT id FROM {$bp->profile->table_name_fields} ORDER BY RAND() LIMIT 1";
     801                $result   = $wpdb->get_results( $wpdb->prepare( "SELECT pf.type, pf.name, pd.value, pf.id FROM {$bp->profile->table_name_data} pd INNER JOIN {$bp->profile->table_name_fields} pf ON pd.field_id = pf.id AND pd.user_id = %d {$exclude_sql} WHERE pf.id IN ($rand_sql)", $user_id ) );
     802
     803                // Collect multiple values in array
     804                if ( bp_xprofile_field_supports_multiple_values( $result[0]->id ) ) {
     805                        // TODO: no stripslashing here? See ::populate()
     806                        $result[0]->value = wp_list_pluck( $result, 'value' );
     807
     808                        // Parse empty list
     809                        if ( array() === maybe_unserialize( $result[0]->value ) ) {
     810                                $result[0]->value = array();
     811                        }
     812
     813                        $result = array( $result[0] );
     814                }
     815
     816                return $result;
    666817        }
    667818
    668819        /**