Ticket #6789: 6789.03.patch
File 6789.03.patch, 18.4 KB (added by , 4 years 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 a0c9481..3542cb5 100644
a b function xprofile_filter_kses( $content, $data_obj = null ) { 156 156 * @since 1.2.6 157 157 * 158 158 * @param string $field_value Field value being santized. 159 * @param int $ field_id FieldID being sanitized.159 * @param int $data_id Data ID being sanitized. 160 160 * @param bool $reserialize Whether to reserialize arrays before returning. Defaults to true. 161 161 * @param object|null $data_obj The BP_XProfile_ProfileData object. 162 162 * @return string 163 163 */ 164 function xprofile_sanitize_data_value_before_save( $field_value, $ field_id = 0, $reserialize = true, $data_obj = null ) {164 function xprofile_sanitize_data_value_before_save( $field_value, $data_id = 0, $reserialize = true, $data_obj = null ) { 165 165 166 166 // Return if empty. 167 167 if ( empty( $field_value ) ) { -
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 21ffe7b..49d6a3a 100644
a b function xprofile_get_field_data( $field, $user_id = 0, $multi_format = 'array' 361 361 362 362 $values = maybe_unserialize( BP_XProfile_ProfileData::get_value_byid( $field_id, $user_id ) ); 363 363 364 if ( is_array( $values ) ) { 364 // Consider multiple values 365 if ( bp_xprofile_field_supports_multiple_values( $field_id ) ) { 366 $values = array_map( 'maybe_unserialize', $values ); 365 367 $data = array(); 366 368 foreach( (array) $values as $value ) { 367 369 … … function xprofile_set_field_data( $field, $user_id, $value, $is_required = false 464 466 $field = new BP_XProfile_ProfileData(); 465 467 $field->field_id = $field_id; 466 468 $field->user_id = $user_id; 467 $field->value = maybe_serialize( $value ); 469 470 // Consider multiple values 471 if ( bp_xprofile_field_supports_multiple_values( $field_id ) ) { 472 $field->value = array_map( 'maybe_serialize', $value ); 473 } else { 474 $field->value = maybe_serialize( $value ); 475 } 468 476 469 477 return $field->save(); 470 478 } … … function xprofile_get_random_profile_data( $user_id, $exclude_fullname = true ) 638 646 * Formats a profile field according to its type. [ TODO: Should really be moved to filters ] 639 647 * 640 648 * @since 1.0.0 649 * @since 2.9.0 The `$field_value` parameter can be an array. 641 650 * 642 * @param string $field_type The type of field: datebox, selectbox, textbox etc.643 * @param string $field_value The actual value.651 * @param string $field_type The type of field: datebox, selectbox, textbox etc. 652 * @param string|array $field_value The actual value. 644 653 * @return string|bool The formatted value, or false if value is empty. 645 654 */ 646 655 function xprofile_format_profile_field( $field_type, $field_value ) { … … function bp_xprofile_is_richtext_enabled_for_field( $field_id = null ) { 1130 1139 } 1131 1140 1132 1141 /** 1142 * Does this profile field support multiple values? 1143 * 1144 * @since 2.9.0 1145 * 1146 * @param int|null $field_id Optional. Default current field ID. 1147 * @return bool Whether the field supports multiple values 1148 */ 1149 function bp_xprofile_field_supports_multiple_values( $field_id = null ) { 1150 if ( ! $field_id ) { 1151 $field_id = bp_get_the_profile_field_id(); 1152 } 1153 1154 $field = xprofile_get_field( $field_id, null, false ); 1155 1156 $supports = false; 1157 if ( $field instanceof BP_XProfile_Field ) { 1158 $supports = (bool) $field->type_obj->supports_multiple_values; 1159 } 1160 1161 /** 1162 * Filters whether the given field supports multiple values. 1163 * 1164 * @since 2.9.0 1165 * 1166 * @param bool $supports True if the field supports multiple values, otherwise false. 1167 * @param int $field_id ID of the field. 1168 */ 1169 return (bool) apply_filters( 'bp_xprofile_field_supports_multiple_values', $supports, $field_id ); 1170 } 1171 1172 /** 1133 1173 * Get visibility levels out of the $bp global. 1134 1174 * 1135 1175 * @since 1.6.0 -
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 63723da..ec7c791 100644
a b function bp_the_profile_field_visibility_level_label() { 907 907 * Return unserialized profile field data. 908 908 * 909 909 * @since 1.0.0 910 * @since 2.9.0 The `$value` parameter can be an array. 910 911 * 911 * @param string $value Content to maybe unserialize.912 * @param string|array $value Content to maybe unserialize. 912 913 * @return string 913 914 */ 914 915 function bp_unserialize_profile_field( $value ) { 915 if ( is_serialized( $value) ) {916 $field_value = maybe_unserialize( $value);916 if ( is_serialized( $value ) || is_array( $value ) ) { 917 $field_value = maybe_unserialize( $value ); 917 918 $field_value = implode( ', ', $field_value ); 918 919 return $field_value; 919 920 } -
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 7267ad9..a4a2167 100644
a b class BP_XProfile_Field_Type_Checkbox extends BP_XProfile_Field_Type { 28 28 $this->category = _x( 'Multi Fields', 'xprofile field type category', 'buddypress' ); 29 29 $this->name = _x( 'Checkboxes', 'xprofile field type', 'buddypress' ); 30 30 31 $this->supports_multiple_values = true; 31 32 $this->supports_multiple_defaults = true; 32 33 $this->accepts_null_value = true; 33 34 $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 5ecaa10..af92d00 100644
a b class BP_XProfile_Field_Type_Multiselectbox extends BP_XProfile_Field_Type { 28 28 $this->category = _x( 'Multi Fields', 'xprofile field type category', 'buddypress' ); 29 29 $this->name = _x( 'Multi Select Box', 'xprofile field type', 'buddypress' ); 30 30 31 $this->supports_multiple_values = true; 31 32 $this->supports_multiple_defaults = true; 32 33 $this->accepts_null_value = true; 33 34 $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 f282a82..75035dd 100644
a b abstract class BP_XProfile_Field_Type { 66 66 public $supports_options = false; 67 67 68 68 /** 69 * If allowed to store multiple values. 70 * 71 * @since 2.9.0 72 * @var bool Does this field support multiple values? e.g. multiselectbox, checkbox. 73 */ 74 public $supports_multiple_values = false; 75 76 /** 69 77 * If allowed to support multiple options as default. 70 78 * 71 79 * @since 2.0.0 -
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 62603e7..9dfdbe8 100644
a b class BP_XProfile_ProfileData { 89 89 $bp = buddypress(); 90 90 91 91 $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_r ow( $sql );92 $profiledata = $wpdb->get_results( $sql ); 93 93 94 94 if ( $profiledata ) { 95 95 wp_cache_set( $cache_key, $profiledata, 'bp_xprofile_data' ); … … class BP_XProfile_ProfileData { 97 97 } 98 98 99 99 if ( $profiledata ) { 100 $this->id = (int) $profiledata->id; 101 $this->user_id = (int) $profiledata->user_id; 102 $this->field_id = (int) $profiledata->field_id; 103 $this->value = stripslashes( $profiledata->value ); 104 $this->last_updated = $profiledata->last_updated; 100 $this->id = (int) $profiledata[0]->id; 101 $this->user_id = (int) $profiledata[0]->user_id; 102 $this->field_id = (int) $profiledata[0]->field_id; 103 $this->last_updated = $profiledata[0]->last_updated; 104 105 // Collect multiple values per field 106 if ( bp_xprofile_field_supports_multiple_values( $this->field_id ) ) { 107 $this->value = array_map( 'stripslashes', wp_list_pluck( $profiledata, 'value' ) ); 108 } else { 109 $this->value = stripslashes( $profiledata[0]->value ); 110 } 105 111 106 112 } else { 107 113 // When no row is found, we'll need to set these properties manually. … … class BP_XProfile_ProfileData { 184 190 185 191 $bp = buddypress(); 186 192 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 ); 193 /** 194 * Filters the data's user ID before saving to the database. 195 * 196 * @since 1.0.0 197 * 198 * @param int $user_id The user ID. 199 * @param int $data_id The field data ID. 200 */ 201 $this->user_id = apply_filters( 'xprofile_data_user_id_before_save', $this->user_id, $this->id ); 202 203 /** 204 * Filters the data's field ID before saving to the database. 205 * 206 * @since 1.0.0 207 * 208 * @param int $field_id The field ID. 209 * @param int $data_id The field data ID. 210 */ 211 $this->field_id = apply_filters( 'xprofile_data_field_id_before_save', $this->field_id, $this->id ); 212 213 /** 214 * Filters the data's value before saving to the database. 215 * 216 * @since 1.0.0 217 * 218 * @param string $field_value The field value. 219 * @param int $data_id The field data ID. 220 * @param bool $reserialize Whether to reserialize the array before returning. Defaults to true. 221 * @param BP_XProfile_ProfileData $data_obj The current field data object. 222 */ 223 $this->value = apply_filters( 'xprofile_data_value_before_save', $this->value, $this->id, true, $this ); 224 225 /** 226 * Filters the data's last updated timestamp before saving to the database. 227 * 228 * @since 1.0.0 229 * 230 * @param int $last_updated The last updated timestamp. 231 * @param int $data_id The field data ID. 232 */ 190 233 $this->last_updated = apply_filters( 'xprofile_data_last_updated_before_save', bp_core_current_time(), $this->id ); 191 234 192 235 /** … … class BP_XProfile_ProfileData { 201 244 do_action_ref_array( 'xprofile_data_before_save', array( $this ) ); 202 245 203 246 if ( $this->is_valid_field() ) { 204 if ( $this->exists() && strlen( trim( $this->value ) ) ) { 247 248 // Store as multiple values 249 if ( $this->exists() && ! empty( $this->value ) && bp_xprofile_field_supports_multiple_values( $this->field_id ) ) { 250 251 // Delete previous rows. 252 $this->delete(); 253 254 // Store each value in a separate row 255 foreach ( array_values( (array) $this->value ) as $k => $value ) { 256 $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 ) ); 257 258 // Use the first inserted id as the new data identifier 259 if ( 0 === $k ) { 260 $this->id = $wpdb->insert_id; 261 } 262 } 263 264 // Store as single value 265 } elseif ( $this->exists() && strlen( trim( $value ) ) ) { 205 266 $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 ) ); 206 267 207 268 } elseif ( $this->exists() && empty( $this->value ) ) { … … class BP_XProfile_ProfileData { 299 360 // Rekey. 300 361 $queried_data = array(); 301 362 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; 363 364 // Set initial field data 365 if ( ! isset( $queried_data[ $ud->field_id ] ) ) { 366 $d = new stdClass; 367 $d->id = $ud->id; 368 $d->user_id = $ud->user_id; 369 $d->field_id = $ud->field_id; 370 $d->last_updated = $ud->last_updated; 371 372 // Collect multiple values in array 373 // TODO: no stripslashing here? See ::populate() 374 if ( bp_xprofile_field_supports_multiple_values( $ud->field_id ) ) { 375 $d->value = array( $ud->value ); 376 } else { 377 $d->value = $ud->value; 378 } 379 380 $queried_data[ $ud->field_id ] = $d; 381 382 // Collect multiple values per field 383 } elseif ( bp_xprofile_field_supports_multiple_values( $ud->field_id ) ) { 384 // TODO: no stripslashing here? See ::populate() 385 $queried_data[ $ud->field_id ]->value[] = $ud->value; 386 } 310 387 } 311 388 312 389 // Set caches. … … class BP_XProfile_ProfileData { 325 402 $d->id = ''; 326 403 $d->user_id = $user_id; 327 404 $d->field_id = $field_id; 328 $d->value = '';405 $d->value = bp_xprofile_field_supports_multiple_values( $field_id ) ? array() : ''; 329 406 $d->last_updated = ''; 330 407 331 408 wp_cache_set( $cache_key, $d, 'bp_xprofile_data' ); … … class BP_XProfile_ProfileData { 405 482 * Get the user's field data id by the id of the xprofile field. 406 483 * 407 484 * @since 1.6.0 485 * @since 2.9.0 Returns the first/main data id in case of multiple values. 408 486 * 409 487 * @param int $field_id Field ID being queried for. 410 488 * @param int $user_id User ID associated with field. … … class BP_XProfile_ProfileData { 471 549 $bp = buddypress(); 472 550 $uncached_ids_sql = implode( ',', $uncached_ids ); 473 551 $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 ) ); 552 $multiple = bp_xprofile_field_supports_multiple_values( $field_id ); 474 553 475 554 // Rekey. 476 555 $qd = array(); 477 556 foreach ( $queried_data as $data ) { 478 $qd[ $data->user_id ] = $data; 557 558 // Set initial user data 559 if ( ! isset( $qd[ $data->user_id ] ) ) { 560 561 // Collect multiple values in array 562 if ( $multiple ) { 563 // TODO: no stripslashing here? See ::populate(). 564 $data->value = array( $data->value ); 565 } 566 567 $qd[ $data->user_id ] = $data; 568 569 // Collect multiple values per field 570 } elseif ( $multiple ) { 571 // TODO: no stripslashing here? See ::populate(). 572 $qd[ $data->user_id ]->value[] = $data->value; 573 } 479 574 } 480 575 481 576 foreach ( $uncached_ids as $id ) { … … class BP_XProfile_ProfileData { 490 585 $d->id = ''; 491 586 $d->user_id = $id; 492 587 $d->field_id = $field_id; 493 $d->value = '';588 $d->value = $multiple ? array() : ''; 494 589 $d->last_updated = ''; 495 590 } 496 591 … … class BP_XProfile_ProfileData { 566 661 $field_sql .= $wpdb->prepare( "AND f.name = %s", $fields ); 567 662 } 568 663 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 );664 $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 ); 570 665 $values = $wpdb->get_results( $sql ); 571 666 667 // TODO: checking for empty result/WP_Error, but not in other methods? 572 668 if ( empty( $values ) || is_wp_error( $values ) ) { 573 669 return false; 574 670 } … … class BP_XProfile_ProfileData { 579 675 for ( $i = 0, $count = count( $values ); $i < $count; ++$i ) { 580 676 for ( $j = 0; $j < count( $fields ); $j++ ) { 581 677 if ( $values[$i]->name == $fields[$j] ) { 582 $new_values[$fields[$j]] = $values[$i]->value; 678 $multiple = bp_xprofile_field_supports_multiple_values( $values[$i]->id ); 679 680 // TODO: no stripslashing here? See ::populate() 681 if ( ! isset( $new_values[ $fields[$j] ] ) ) { 682 $new_values[$fields[$j]] = $multiple ? array( $values[$i]->value ) : $values[$i]->value; 683 } elseif ( $multiple ) { 684 $new_values[$fields[$j]][] = $values[$i]->value; 685 } 583 686 } elseif ( !array_key_exists( $fields[$j], $new_values ) ) { 584 687 $new_values[$fields[$j]] = NULL; 585 688 } 586 689 } 587 690 } 588 691 } else { 589 $new_values = $values[0]->value; 692 693 // Collect multiple values in array 694 // TODO: no stripslashing here? See ::populate() 695 if ( bp_xprofile_field_supports_multiple_values( $values[0]->id ) ) { 696 $new_values = wp_list_pluck( $values, 'value' ); 697 } else { 698 $new_values = $values[0]->value; 699 } 590 700 } 591 701 592 702 return $new_values; … … class BP_XProfile_ProfileData { 651 761 * 652 762 * @since 1.0.0 653 763 * 654 * @param int 655 * @param string $exclude_fullname SQL portion used to exclude by field ID.764 * @param int $user_id User ID to query for. 765 * @param bool $exclude_fullname Optional. Whether to exclude the fullname field. Defaults to false. 656 766 * @return array|null|object 657 767 */ 658 public static function get_random( $user_id, $exclude_fullname ) {768 public static function get_random( $user_id, $exclude_fullname = false ) { 659 769 global $wpdb; 660 770 661 771 $exclude_sql = ! empty( $exclude_fullname ) ? ' AND pf.id != 1' : ''; 662 772 663 773 $bp = buddypress(); 664 774 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 ) ); 775 $rand_sql = "SELECT id FROM {$bp->profile->table_name_fields} ORDER BY RAND() LIMIT 1"; 776 $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 ) ); 777 778 // Collect multiple values in array 779 if ( bp_xprofile_field_supports_multiple_values( $result[0]->id ) ) { 780 // TODO: no stripslashing here? See ::populate() 781 $result->value = wp_list_pluck( $result, 'value' ); 782 $result = $result[0]; 783 } 784 785 return $result; 666 786 } 667 787 668 788 /**