[ Index ] |
PHP Cross Reference of BuddyPress |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * BuddyPress XProfile Filters. 4 * 5 * Business functions are where all the magic happens in BuddyPress. They will 6 * handle the actual saving or manipulation of information. Usually they will 7 * hand off to a database class for data access, then return 8 * true or false on success or failure. 9 * 10 * @package BuddyPress 11 * @subpackage XProfileFunctions 12 * @since 1.5.0 13 */ 14 15 // Exit if accessed directly. 16 defined( 'ABSPATH' ) || exit; 17 18 /*** Field Group Management **************************************************/ 19 20 /** 21 * Fetch a set of field groups, populated with fields and field data. 22 * 23 * Procedural wrapper for BP_XProfile_Group::get() method. 24 * 25 * @since 2.1.0 26 * 27 * @param array $args See {@link BP_XProfile_Group::get()} for description of arguments. 28 * @return array $groups 29 */ 30 function bp_xprofile_get_groups( $args = array() ) { 31 32 $groups = BP_XProfile_Group::get( $args ); 33 34 /** 35 * Filters a set of field groups, populated with fields and field data. 36 * 37 * @since 2.1.0 38 * 39 * @param array $groups Array of field groups and field data. 40 * @param array $args Array of arguments used to query for groups. 41 */ 42 return apply_filters( 'bp_xprofile_get_groups', $groups, $args ); 43 } 44 45 /** 46 * Insert a new profile field group. 47 * 48 * @since 1.0.0 49 * 50 * @param array|string $args { 51 * Array of arguments for field group insertion. 52 * 53 * @type int|bool $field_group_id ID of the field group to insert into. 54 * @type string|bool $name Name of the group. 55 * @type string $description Field group description. 56 * @type bool $can_delete Whether or not the field group can be deleted. 57 * } 58 * @return boolean 59 */ 60 function xprofile_insert_field_group( $args = '' ) { 61 62 // Parse the arguments. 63 $r = bp_parse_args( 64 $args, 65 array( 66 'field_group_id' => false, 67 'name' => false, 68 'description' => '', 69 'can_delete' => true, 70 ), 71 'xprofile_insert_field_group' 72 ); 73 74 // Bail if no group name. 75 if ( empty( $r['name'] ) ) { 76 return false; 77 } 78 79 // Create new field group object, maybe using an existing ID. 80 $field_group = new BP_XProfile_Group( $r['field_group_id'] ); 81 $field_group->name = $r['name']; 82 $field_group->description = $r['description']; 83 $field_group->can_delete = $r['can_delete']; 84 85 return $field_group->save(); 86 } 87 88 /** 89 * Get a specific profile field group. 90 * 91 * @since 1.0.0 92 * 93 * @param int $field_group_id Field group ID to fetch. 94 * @return false|BP_XProfile_Group 95 */ 96 function xprofile_get_field_group( $field_group_id = 0 ) { 97 98 // Try to get a specific field group by ID. 99 $field_group = new BP_XProfile_Group( $field_group_id ); 100 101 // Bail if group was not found. 102 if ( empty( $field_group->id ) ) { 103 return false; 104 } 105 106 // Return field group. 107 return $field_group; 108 } 109 110 /** 111 * Delete a specific profile field group. 112 * 113 * @since 1.0.0 114 * 115 * @param int $field_group_id Field group ID to delete. 116 * @return boolean 117 */ 118 function xprofile_delete_field_group( $field_group_id = 0 ) { 119 120 // Try to get a specific field group by ID. 121 $field_group = xprofile_get_field_group( $field_group_id ); 122 123 // Bail if group was not found. 124 if ( false === $field_group ) { 125 return false; 126 } 127 128 // Return the results of trying to delete the field group. 129 return $field_group->delete(); 130 } 131 132 /** 133 * Update the position of a specific profile field group. 134 * 135 * @since 1.0.0 136 * 137 * @param int $field_group_id Field group ID to update. 138 * @param int $position Field group position to update to. 139 * @return boolean 140 */ 141 function xprofile_update_field_group_position( $field_group_id = 0, $position = 0 ) { 142 return BP_XProfile_Group::update_position( $field_group_id, $position ); 143 } 144 145 /*** Field Management *********************************************************/ 146 147 /** 148 * Get details of all xprofile field types. 149 * 150 * @since 2.0.0 151 * 152 * @return array Key/value pairs (field type => class name). 153 */ 154 function bp_xprofile_get_field_types() { 155 $fields = array( 156 'checkbox' => 'BP_XProfile_Field_Type_Checkbox', 157 'datebox' => 'BP_XProfile_Field_Type_Datebox', 158 'multiselectbox' => 'BP_XProfile_Field_Type_Multiselectbox', 159 'number' => 'BP_XProfile_Field_Type_Number', 160 'url' => 'BP_XProfile_Field_Type_URL', 161 'radio' => 'BP_XProfile_Field_Type_Radiobutton', 162 'selectbox' => 'BP_XProfile_Field_Type_Selectbox', 163 'textarea' => 'BP_XProfile_Field_Type_Textarea', 164 'textbox' => 'BP_XProfile_Field_Type_Textbox', 165 'telephone' => 'BP_XProfile_Field_Type_Telephone', 166 'wp-biography' => 'BP_XProfile_Field_Type_WordPress_Biography', 167 'wp-textbox' => 'BP_XProfile_Field_Type_WordPress_Textbox', 168 'checkbox_acceptance' => 'BP_XProfile_Field_Type_Checkbox_Acceptance', 169 ); 170 171 /** 172 * Filters the list of all xprofile field types. 173 * 174 * If you've added a custom field type in a plugin, register it with this filter. 175 * 176 * @since 2.0.0 177 * 178 * @param array $fields Array of field type/class name pairings. 179 */ 180 return apply_filters( 'bp_xprofile_get_field_types', $fields ); 181 } 182 183 /** 184 * Creates the specified field type object; used for validation and templating. 185 * 186 * @since 2.0.0 187 * 188 * @param string $type Type of profile field to create. See {@link bp_xprofile_get_field_types()} for default core values. 189 * @return object $value If field type unknown, returns BP_XProfile_Field_Type_Textarea. 190 * Otherwise returns an instance of the relevant child class of BP_XProfile_Field_Type. 191 */ 192 function bp_xprofile_create_field_type( $type ) { 193 194 $field = bp_xprofile_get_field_types(); 195 $class = isset( $field[$type] ) ? $field[$type] : ''; 196 197 /** 198 * To handle (missing) field types, fallback to a placeholder field object if a type is unknown. 199 */ 200 if ( $class && class_exists( $class ) ) { 201 return new $class; 202 } else { 203 return new BP_XProfile_Field_Type_Placeholder; 204 } 205 } 206 207 /** 208 * Insert or update an xprofile field. 209 * 210 * @since 1.1.0 211 * 212 * @param array|string $args { 213 * Array of arguments. 214 * @type int $field_id Optional. Pass the ID of an existing field to edit that field. 215 * @type int $field_group_id ID of the associated field group. 216 * @type int $parent_id Optional. ID of the parent field. 217 * @type string $type Field type. Checked against a list of allowed field_types. 218 * @type string $name Name of the new field. 219 * @type string $description Optional. Descriptive text for the field. 220 * @type bool $is_required Optional. Whether users must provide a value for the field. Default: false. 221 * @type bool $can_delete Optional. Whether admins can delete this field in the Dashboard interface. 222 * Generally this is false only for the Name field, which is required throughout BP. 223 * Default: true. 224 * @type string $order_by Optional. For field types that support options (such as 'radio'), this flag 225 * determines whether the sort order of the options will be 'default' 226 * (order created) or 'custom'. 227 * @type bool $is_default_option Optional. For the 'option' field type, setting this value to true means that 228 * it'll be the default value for the parent field when the user has not yet 229 * overridden. Default: true. 230 * @type int $option_order Optional. For the 'option' field type, this determines the order in which the 231 * options appear. 232 * } 233 * @return bool|int False on failure, ID of new field on success. 234 */ 235 function xprofile_insert_field( $args = '' ) { 236 237 $r = bp_parse_args( 238 $args, 239 array( 240 'field_id' => null, 241 'field_group_id' => null, 242 'parent_id' => null, 243 'type' => '', 244 'name' => '', 245 'description' => '', 246 'is_required' => false, 247 'can_delete' => true, 248 'order_by' => '', 249 'is_default_option' => false, 250 'option_order' => null, 251 'field_order' => null, 252 ) 253 ); 254 255 // Field_group_id is required. 256 if ( empty( $r['field_group_id'] ) ) { 257 return false; 258 } 259 260 // Check this is a non-empty, valid field type. 261 if ( ! in_array( $r['type'], (array) buddypress()->profile->field_types ) ) { 262 return false; 263 } 264 265 // Instantiate a new field object. 266 if ( ! empty( $r['field_id'] ) ) { 267 $field = xprofile_get_field( $r['field_id'], null, false ); 268 } else { 269 $field = new BP_XProfile_Field; 270 } 271 272 $field->group_id = $r['field_group_id']; 273 $field->type = $r['type']; 274 275 // The 'name' field cannot be empty. 276 if ( ! empty( $r['name'] ) ) { 277 $field->name = $r['name']; 278 } 279 280 $field->description = $r['description']; 281 $field->order_by = $r['order_by']; 282 $field->parent_id = (int) $r['parent_id']; 283 $field->field_order = (int) $r['field_order']; 284 $field->option_order = (int) $r['option_order']; 285 $field->is_required = (bool) $r['is_required']; 286 $field->can_delete = (bool) $r['can_delete']; 287 $field->is_default_option = (bool) $r['is_default_option']; 288 289 return $field->save(); 290 } 291 292 /** 293 * Get a profile field object. 294 * 295 * @since 1.1.0 296 * @since 2.8.0 Added `$user_id` and `$get_data` parameters. 297 * 298 * @param int|object $field ID of the field or object representing field data. 299 * @param int|null $user_id Optional. ID of the user associated with the field. 300 * Ignored if `$get_data` is false. If `$get_data` is 301 * true, but no `$user_id` is provided, defaults to 302 * logged-in user ID. 303 * @param bool $get_data Whether to fetch data for the specified `$user_id`. 304 * @return BP_XProfile_Field|null Field object if found, otherwise null. 305 */ 306 function xprofile_get_field( $field, $user_id = null, $get_data = true ) { 307 if ( $field instanceof BP_XProfile_Field ) { 308 $_field = $field; 309 } elseif ( is_object( $field ) ) { 310 $_field = new BP_XProfile_Field(); 311 $_field->fill_data( $field ); 312 } else { 313 $_field = BP_XProfile_Field::get_instance( $field, $user_id, $get_data ); 314 } 315 316 if ( ! $_field ) { 317 return null; 318 } 319 320 return $_field; 321 } 322 323 /** 324 * Get a profile Field Type object. 325 * 326 * @since 8.0.0 327 * 328 * @param int $field_id ID of the field. 329 * @return BP_XProfile_Field_Type|null Field Type object if found, otherwise null. 330 */ 331 function bp_xprofile_get_field_type( $field_id ) { 332 $field_type = null; 333 $field = xprofile_get_field( $field_id, null, false ); 334 335 if ( $field instanceof BP_XProfile_Field ) { 336 $field_type = $field->type_obj; 337 } 338 339 return $field_type; 340 } 341 342 /** 343 * Delete a profile field object. 344 * 345 * @since 1.1.0 346 * 347 * @param int|object $field_id ID of the field or object representing field data. 348 * @return bool Whether or not the field was deleted. 349 */ 350 function xprofile_delete_field( $field_id ) { 351 $field = new BP_XProfile_Field( $field_id ); 352 return $field->delete(); 353 } 354 355 /*** Field Data Management *****************************************************/ 356 357 358 /** 359 * Fetches profile data for a specific field for the user. 360 * 361 * When the field value is serialized, this function unserializes and filters 362 * each item in the array. 363 * 364 * @since 1.0.0 365 * 366 * @param mixed $field The ID of the field, or the $name of the field. 367 * @param int $user_id The ID of the user. 368 * @param string $multi_format How should array data be returned? 'comma' if you want a 369 * comma-separated string; 'array' if you want an array. 370 * @return mixed The profile field data. 371 */ 372 function xprofile_get_field_data( $field, $user_id = 0, $multi_format = 'array' ) { 373 374 if ( empty( $user_id ) ) { 375 $user_id = bp_displayed_user_id(); 376 } 377 378 if ( empty( $user_id ) ) { 379 return false; 380 } 381 382 if ( is_numeric( $field ) ) { 383 $field_id = $field; 384 } else { 385 $field_id = xprofile_get_field_id_from_name( $field ); 386 } 387 388 if ( empty( $field_id ) ) { 389 return false; 390 } 391 392 $values = maybe_unserialize( BP_XProfile_ProfileData::get_value_byid( $field_id, $user_id ) ); 393 394 if ( is_array( $values ) ) { 395 $data = array(); 396 foreach( (array) $values as $value ) { 397 398 /** 399 * Filters the field data value for a specific field for the user. 400 * 401 * @since 1.0.0 402 * 403 * @param string $value Value saved for the field. 404 * @param int $field_id ID of the field being displayed. 405 * @param int $user_id ID of the user being displayed. 406 */ 407 $data[] = apply_filters( 'xprofile_get_field_data', $value, $field_id, $user_id ); 408 } 409 410 if ( 'comma' == $multi_format ) { 411 $data = implode( ', ', $data ); 412 } 413 } else { 414 /** This filter is documented in bp-xprofile/bp-xprofile-functions.php */ 415 $data = apply_filters( 'xprofile_get_field_data', $values, $field_id, $user_id ); 416 } 417 418 return $data; 419 } 420 421 /** 422 * A simple function to set profile data for a specific field for a specific user. 423 * 424 * @since 1.0.0 425 * 426 * @param int|string $field The ID of the field, or the $name of the field. 427 * @param int $user_id The ID of the user. 428 * @param mixed $value The value for the field you want to set for the user. 429 * @param bool $is_required Whether or not the field is required. 430 * @return bool True on success, false on failure. 431 */ 432 function xprofile_set_field_data( $field, $user_id, $value, $is_required = false ) { 433 434 if ( is_numeric( $field ) ) { 435 $field_id = $field; 436 } else { 437 $field_id = xprofile_get_field_id_from_name( $field ); 438 } 439 440 if ( empty( $field_id ) ) { 441 return false; 442 } 443 444 $field = xprofile_get_field( $field_id ); 445 $field_type = BP_XProfile_Field::get_type( $field_id ); 446 $field_type_obj = bp_xprofile_create_field_type( $field_type ); 447 448 /** 449 * Filter the raw submitted profile field value. 450 * 451 * Use this filter to modify the values submitted by users before 452 * doing field-type-specific validation. 453 * 454 * @since 2.1.0 455 * 456 * @param mixed $value Value passed to xprofile_set_field_data(). 457 * @param BP_XProfile_Field $field Field object. 458 * @param BP_XProfile_Field_Type $field_type_obj Field type object. 459 */ 460 $value = apply_filters( 'bp_xprofile_set_field_data_pre_validate', $value, $field, $field_type_obj ); 461 462 // Special-case support for integer 0 for the number field type. 463 if ( $is_required && ! is_integer( $value ) && $value !== '0' && ( empty( $value ) || ! is_array( $value ) && ! strlen( trim( $value ) ) ) ) { 464 return false; 465 } 466 467 /** 468 * Certain types of fields (checkboxes, multiselects) may come through empty. 469 * Save as empty array so this isn't overwritten by the default on next edit. 470 * 471 * Special-case support for integer 0 for the number field type 472 */ 473 if ( empty( $value ) && ! is_integer( $value ) && $value !== '0' && $field_type_obj->accepts_null_value ) { 474 $value = array(); 475 } 476 477 // If the value is empty, then delete any field data that exists, unless the field is of a type 478 // where null values are semantically meaningful. 479 if ( empty( $value ) && ! is_integer( $value ) && $value !== '0' && ! $field_type_obj->accepts_null_value ) { 480 xprofile_delete_field_data( $field_id, $user_id ); 481 return true; 482 } 483 484 // For certain fields, only certain parameters are acceptable, so add them to the list of allowed values. 485 if ( $field_type_obj->supports_options ) { 486 $field_type_obj->set_allowed_values( wp_list_pluck( $field->get_children(), 'name' ) ); 487 } 488 489 // Check the value is in an accepted format for this form field. 490 if ( ! $field_type_obj->is_valid( $value ) ) { 491 return false; 492 } 493 494 $field_args = compact( 'field_type_obj', 'field', 'user_id', 'value', 'is_required' ); 495 496 /** 497 * Return a WP_Error object or true to use your custom way of saving field values. 498 * 499 * @since 8.0.0 500 * 501 * @param boolean Whether to shortcircuit the $bp->profile->table_name_data table. 502 * @param array $field_args { 503 * An array of arguments. 504 * 505 * @type object $field_type_obj Field type object. 506 * @type BP_XProfile_Field $field Field object. 507 * @type integer $user_id The user ID. 508 * @type mixed $value Value passed to xprofile_set_field_data(). 509 * @type boolean $is_required Whether or not the field is required. 510 * } 511 */ 512 $retval = apply_filters( 'bp_xprofile_set_field_data_pre_save', false, $field_args ); 513 514 if ( is_wp_error( $retval ) ) { 515 return false; 516 } 517 518 if ( false === $retval ) { 519 $field = new BP_XProfile_ProfileData(); 520 $field->field_id = $field_id; 521 $field->user_id = $user_id; 522 523 // Gets un/reserialized via xprofile_sanitize_data_value_before_save(). 524 $field->value = maybe_serialize( $value ); 525 526 $retval = $field->save(); 527 } 528 529 return $retval; 530 } 531 532 /** 533 * Set the visibility level for this field. 534 * 535 * @since 1.6.0 536 * 537 * @param int $field_id The ID of the xprofile field. 538 * @param int $user_id The ID of the user to whom the data belongs. 539 * @param string $visibility_level What the visibility setting should be. 540 * @return bool True on success 541 */ 542 function xprofile_set_field_visibility_level( $field_id = 0, $user_id = 0, $visibility_level = '' ) { 543 if ( empty( $field_id ) || empty( $user_id ) || empty( $visibility_level ) ) { 544 return false; 545 } 546 547 // Check against a list of registered visibility levels. 548 $allowed_values = bp_xprofile_get_visibility_levels(); 549 if ( !array_key_exists( $visibility_level, $allowed_values ) ) { 550 return false; 551 } 552 553 // Stored in an array in usermeta. 554 $current_visibility_levels = bp_get_user_meta( $user_id, 'bp_xprofile_visibility_levels', true ); 555 556 if ( !$current_visibility_levels ) { 557 $current_visibility_levels = array(); 558 } 559 560 $current_visibility_levels[$field_id] = $visibility_level; 561 562 return bp_update_user_meta( $user_id, 'bp_xprofile_visibility_levels', $current_visibility_levels ); 563 } 564 565 /** 566 * Get the visibility level for a field. 567 * 568 * @since 2.0.0 569 * 570 * @param int $field_id The ID of the xprofile field. 571 * @param int $user_id The ID of the user to whom the data belongs. 572 * @return string 573 */ 574 function xprofile_get_field_visibility_level( $field_id = 0, $user_id = 0 ) { 575 $current_level = ''; 576 577 if ( empty( $field_id ) || empty( $user_id ) ) { 578 return $current_level; 579 } 580 581 $current_levels = bp_get_user_meta( $user_id, 'bp_xprofile_visibility_levels', true ); 582 $current_level = isset( $current_levels[ $field_id ] ) ? $current_levels[ $field_id ] : ''; 583 584 // Use the user's stored level, unless custom visibility is disabled. 585 $field = xprofile_get_field( $field_id, null, false ); 586 if ( isset( $field->allow_custom_visibility ) && 'disabled' === $field->allow_custom_visibility ) { 587 $current_level = $field->default_visibility; 588 } 589 590 // If we're still empty, it means that overrides are permitted, but the 591 // user has not provided a value. Use the default value. 592 if ( empty( $current_level ) ) { 593 $current_level = $field->default_visibility; 594 } 595 596 return $current_level; 597 } 598 599 /** 600 * Delete XProfile field data. 601 * 602 * @since 1.1.0 603 * 604 * @param string $field Field to delete. 605 * @param int $user_id User ID to delete field from. 606 * @return bool Whether or not the field was deleted. 607 */ 608 function xprofile_delete_field_data( $field = '', $user_id = 0 ) { 609 610 // Get the field ID. 611 if ( is_numeric( $field ) ) { 612 $field_id = (int) $field; 613 } else { 614 $field_id = xprofile_get_field_id_from_name( $field ); 615 } 616 617 // Bail if field or user ID are empty. 618 if ( empty( $field_id ) || empty( $user_id ) ) { 619 return false; 620 } 621 622 // Get the profile field data to delete. 623 $field = new BP_XProfile_ProfileData( $field_id, $user_id ); 624 625 // Delete the field data. 626 return $field->delete(); 627 } 628 629 /** 630 * Check if field is a required field. 631 * 632 * @since 1.1.0 633 * 634 * @param int $field_id ID of the field to check for. 635 * @return bool Whether or not field is required. 636 */ 637 function xprofile_check_is_required_field( $field_id ) { 638 $field = new BP_XProfile_Field( $field_id ); 639 $retval = false; 640 641 if ( isset( $field->is_required ) ) { 642 $retval = $field->is_required; 643 } 644 645 return (bool) $retval; 646 } 647 648 /** 649 * Returns the ID for the field based on the field name. 650 * 651 * @since 1.0.0 652 * 653 * @param string $field_name The name of the field to get the ID for. 654 * @return int|null $field_id on success, false on failure. 655 */ 656 function xprofile_get_field_id_from_name( $field_name ) { 657 return BP_XProfile_Field::get_id_from_name( $field_name ); 658 } 659 660 /** 661 * Fetches a random piece of profile data for the user. 662 * 663 * @since 1.0.0 664 * 665 * @global BuddyPress $bp The one true BuddyPress instance. 666 * @global object $wpdb WordPress DB access object. 667 * @global object $current_user WordPress global variable containing current logged in user information. 668 * 669 * @param int $user_id User ID of the user to get random data for. 670 * @param bool $exclude_fullname Optional; whether or not to exclude the full name field as random data. 671 * Defaults to true. 672 * @return string|bool The fetched random data for the user, or false if no data or no match. 673 */ 674 function xprofile_get_random_profile_data( $user_id, $exclude_fullname = true ) { 675 $field_data = BP_XProfile_ProfileData::get_random( $user_id, $exclude_fullname ); 676 677 if ( empty( $field_data ) ) { 678 return false; 679 } 680 681 $field_data[0]->value = xprofile_format_profile_field( $field_data[0]->type, $field_data[0]->value ); 682 683 if ( empty( $field_data[0]->value ) ) { 684 return false; 685 } 686 687 /** 688 * Filters a random piece of profile data for the user. 689 * 690 * @since 1.0.0 691 * 692 * @param array $field_data Array holding random profile data. 693 */ 694 return apply_filters( 'xprofile_get_random_profile_data', $field_data ); 695 } 696 697 /** 698 * Formats a profile field according to its type. [ TODO: Should really be moved to filters ] 699 * 700 * @since 1.0.0 701 * 702 * @param string $field_type The type of field: datebox, selectbox, textbox etc. 703 * @param string $field_value The actual value. 704 * @return string|bool The formatted value, or false if value is empty. 705 */ 706 function xprofile_format_profile_field( $field_type, $field_value ) { 707 708 if ( empty( $field_value ) ) { 709 return false; 710 } 711 712 $field_value = bp_unserialize_profile_field( $field_value ); 713 714 if ( 'datebox' != $field_type ) { 715 $content = $field_value; 716 $field_value = str_replace( ']]>', ']]>', $content ); 717 } 718 719 return xprofile_filter_format_field_value_by_type( stripslashes_deep( $field_value ), $field_type ); 720 } 721 722 /** 723 * Update the field position for a provided field. 724 * 725 * @since 1.1.0 726 * 727 * @param int $field_id ID of the field to update. 728 * @param int $position Position to update the field to. 729 * @param int $field_group_id Group ID for group the field is in. 730 * @return bool 731 */ 732 function xprofile_update_field_position( $field_id, $position, $field_group_id ) { 733 return BP_XProfile_Field::update_position( $field_id, $position, $field_group_id ); 734 } 735 736 /** 737 * Replace the displayed and logged-in users fullnames with the xprofile name, if required. 738 * 739 * The Members component uses the logged-in user's display_name to set the 740 * value of buddypress()->loggedin_user->fullname. However, in cases where 741 * profile sync is disabled, display_name may diverge from the xprofile 742 * fullname field value, and the xprofile field should take precedence. 743 * 744 * Runs at bp_setup_globals:100 to ensure that all components have loaded their 745 * globals before attempting any overrides. 746 * 747 * @since 2.0.0 748 */ 749 function xprofile_override_user_fullnames() { 750 // If sync is enabled, the two names will match. No need to continue. 751 if ( ! bp_disable_profile_sync() ) { 752 return; 753 } 754 755 if ( bp_loggedin_user_id() ) { 756 buddypress()->loggedin_user->fullname = bp_core_get_user_displayname( bp_loggedin_user_id() ); 757 } 758 759 if ( bp_displayed_user_id() ) { 760 buddypress()->displayed_user->fullname = bp_core_get_user_displayname( bp_displayed_user_id() ); 761 } 762 } 763 add_action( 'bp_setup_globals', 'xprofile_override_user_fullnames', 100 ); 764 765 /** 766 * When search_terms are passed to BP_User_Query, search against xprofile fields. 767 * 768 * @since 2.0.0 769 * 770 * @param array $sql Clauses in the user_id SQL query. 771 * @param BP_User_Query $query User query object. 772 * @return array 773 */ 774 function bp_xprofile_bp_user_query_search( $sql, BP_User_Query $query ) { 775 global $wpdb; 776 777 if ( empty( $query->query_vars['search_terms'] ) || empty( $sql['where']['search'] ) ) { 778 return $sql; 779 } 780 781 $bp = buddypress(); 782 783 $search_terms_clean = bp_esc_like( wp_kses_normalize_entities( $query->query_vars['search_terms'] ) ); 784 785 if ( $query->query_vars['search_wildcard'] === 'left' ) { 786 $search_terms_nospace = '%' . $search_terms_clean; 787 $search_terms_space = '%' . $search_terms_clean . ' %'; 788 } elseif ( $query->query_vars['search_wildcard'] === 'right' ) { 789 $search_terms_nospace = $search_terms_clean . '%'; 790 $search_terms_space = '% ' . $search_terms_clean . '%'; 791 } else { 792 $search_terms_nospace = '%' . $search_terms_clean . '%'; 793 $search_terms_space = '%' . $search_terms_clean . '%'; 794 } 795 796 // Combine the core search (against wp_users) into a single OR clause 797 // with the xprofile_data search. 798 $matched_user_ids = $wpdb->get_col( $wpdb->prepare( 799 "SELECT user_id FROM {$bp->profile->table_name_data} WHERE value LIKE %s OR value LIKE %s", 800 $search_terms_nospace, 801 $search_terms_space 802 ) ); 803 804 if ( ! empty( $matched_user_ids ) ) { 805 $search_core = $sql['where']['search']; 806 $search_combined = " ( u.{$query->uid_name} IN (" . implode(',', $matched_user_ids) . ") OR {$search_core} )"; 807 $sql['where']['search'] = $search_combined; 808 } 809 810 return $sql; 811 } 812 add_action( 'bp_user_query_uid_clauses', 'bp_xprofile_bp_user_query_search', 10, 2 ); 813 814 /** 815 * Syncs Xprofile data to the standard built in WordPress profile data. 816 * 817 * @since 1.0.0 818 * @since 9.2.0 Adds the $args arguments to catch hook's additional arguments. 819 * 820 * @param int $user_id ID of the user to sync. 821 * @param array $args Hook's additional arguments. 822 * @return bool 823 */ 824 function xprofile_sync_wp_profile( $user_id = 0, ...$args ) { 825 826 // Bail if profile syncing is disabled. 827 if ( bp_disable_profile_sync() ) { 828 return true; 829 } 830 831 if ( empty( $user_id ) ) { 832 $user_id = bp_loggedin_user_id(); 833 } 834 835 if ( empty( $user_id ) ) { 836 return false; 837 } 838 839 $fullname_field_id = (int) bp_xprofile_fullname_field_id(); 840 $usermeta = array(); 841 $userdata = array(); 842 843 if ( isset( $args[1]['meta'] ) ) { 844 $usermeta = $args[1]['meta']; 845 } elseif ( isset( $args[3] ) ) { 846 $usermeta = $args[3]; 847 } 848 849 if ( isset( $usermeta['profile_field_ids'] ) ) { 850 $xprofile_fields = wp_parse_id_list( $usermeta['profile_field_ids'] ); 851 $xprofile_fields = array_diff( $xprofile_fields, array( $fullname_field_id ) ); 852 853 foreach ( $xprofile_fields as $xprofile_field_id ) { 854 $field_type = bp_xprofile_get_field_type( $xprofile_field_id ); 855 856 $field_key = 'field_' . $xprofile_field_id; 857 if ( isset( $field_type->wp_user_key ) && isset( $usermeta[ $field_key ] ) && $usermeta[ $field_key ] ) { 858 $userdata[ $field_type->wp_user_key ] = $usermeta[ $field_key ]; 859 } 860 } 861 } 862 863 $fullname = xprofile_get_field_data( $fullname_field_id, $user_id ); 864 $space = strpos( $fullname, ' ' ); 865 866 if ( false === $space ) { 867 if ( ! isset( $userdata['first_name'] ) ) { 868 $userdata['first_name'] = $fullname; 869 } 870 871 if ( ! isset( $userdata['last_name'] ) ) { 872 $userdata['last_name'] = ''; 873 } 874 } else { 875 if ( ! isset( $userdata['first_name'] ) ) { 876 $userdata['first_name'] = substr( $fullname, 0, $space ); 877 } 878 879 if ( ! isset( $userdata['last_name'] ) ) { 880 $userdata['last_name'] = trim( substr( $fullname, $space, strlen( $fullname ) ) ); 881 } 882 } 883 884 bp_update_user_meta( $user_id, 'nickname', $fullname ); 885 bp_update_user_meta( $user_id, 'first_name', $userdata['first_name'] ); 886 bp_update_user_meta( $user_id, 'last_name', $userdata['last_name'] ); 887 888 wp_update_user( array( 'ID' => $user_id, 'display_name' => $fullname ) ); 889 } 890 add_action( 'bp_core_signup_user', 'xprofile_sync_wp_profile', 10, 5 ); 891 add_action( 'bp_core_activated_user', 'xprofile_sync_wp_profile', 10, 3 ); 892 893 /** 894 * Syncs the standard built in WordPress profile data to XProfile. 895 * 896 * @since 1.2.4 897 * 898 * @param object $errors Array of errors. Passed by reference. 899 * @param bool $update Whether or not being upated. 900 * @param object $user User object whose profile is being synced. Passed by reference. 901 */ 902 function xprofile_sync_bp_profile( &$errors, $update, &$user ) { 903 904 // Bail if profile syncing is disabled. 905 if ( bp_disable_profile_sync() || ! $update || $errors->get_error_codes() ) { 906 return; 907 } 908 909 xprofile_set_field_data( bp_xprofile_fullname_field_id(), $user->ID, $user->display_name ); 910 } 911 add_action( 'user_profile_update_errors', 'xprofile_sync_bp_profile', 10, 3 ); 912 913 /** 914 * Update the WP display, last, and first name fields when the xprofile display name field is updated. 915 * 916 * @since 3.0.0 917 * 918 * @param BP_XProfile_ProfileData $data Current instance of the profile data being saved. 919 */ 920 function xprofile_sync_wp_profile_on_single_field_set( $data ) { 921 922 if ( bp_xprofile_fullname_field_id() !== $data->field_id ) { 923 return; 924 } 925 926 xprofile_sync_wp_profile( $data->user_id ); 927 } 928 add_action( 'xprofile_data_after_save', 'xprofile_sync_wp_profile_on_single_field_set' ); 929 930 /** 931 * When a user is deleted, we need to clean up the database and remove all the 932 * profile data from each table. Also we need to clean anything up in the 933 * usermeta table that this component uses. 934 * 935 * @since 1.0.0 936 * 937 * @param int $user_id The ID of the deleted user. 938 */ 939 function xprofile_remove_data( $user_id ) { 940 BP_XProfile_ProfileData::delete_data_for_user( $user_id ); 941 } 942 add_action( 'wpmu_delete_user', 'xprofile_remove_data' ); 943 add_action( 'bp_make_spam_user', 'xprofile_remove_data' ); 944 945 /** 946 * Deletes user XProfile data on the 'delete_user' hook. 947 * 948 * @since 6.0.0 949 * 950 * @param int $user_id The ID of the deleted user. 951 */ 952 function xprofile_remove_data_on_delete_user( $user_id ) { 953 if ( ! bp_remove_user_data_on_delete_user_hook( 'xprofile', $user_id ) ) { 954 return; 955 } 956 957 xprofile_remove_data( $user_id ); 958 } 959 add_action( 'delete_user', 'xprofile_remove_data_on_delete_user' ); 960 961 /*** XProfile Meta ****************************************************/ 962 963 /** 964 * Delete a piece of xprofile metadata. 965 * 966 * @since 1.5.0 967 * 968 * @param int $object_id ID of the object the metadata belongs to. 969 * @param string $object_type Type of object. 'group', 'field', or 'data'. 970 * @param string|bool $meta_key Key of the metadata being deleted. If omitted, all 971 * metadata for the object will be deleted. 972 * @param mixed $meta_value Optional. If provided, only metadata that matches 973 * the value will be permitted. 974 * @param bool $delete_all Optional. If true, delete matching metadata entries 975 * for all objects, ignoring the specified object_id. Otherwise, only 976 * delete matching metadata entries for the specified object. 977 * Default: false. 978 * @return bool True on success, false on failure. 979 */ 980 function bp_xprofile_delete_meta( $object_id, $object_type, $meta_key = false, $meta_value = false, $delete_all = false ) { 981 global $wpdb; 982 983 // Sanitize object type. 984 if ( ! in_array( $object_type, array( 'group', 'field', 'data' ) ) ) { 985 return false; 986 } 987 988 // Legacy - if no meta_key is passed, delete all for the item. 989 if ( empty( $meta_key ) ) { 990 $table_key = 'xprofile_' . $object_type . 'meta'; 991 $table_name = $wpdb->{$table_key}; 992 $keys = $wpdb->get_col( $wpdb->prepare( "SELECT meta_key FROM {$table_name} WHERE object_type = %s AND object_id = %d", $object_type, $object_id ) ); 993 994 // Force delete_all to false if deleting all for object. 995 $delete_all = false; 996 } else { 997 $keys = array( $meta_key ); 998 } 999 1000 add_filter( 'query', 'bp_filter_metaid_column_name' ); 1001 add_filter( 'query', 'bp_xprofile_filter_meta_query' ); 1002 1003 $retval = false; 1004 foreach ( $keys as $key ) { 1005 $retval = delete_metadata( 'xprofile_' . $object_type, $object_id, $key, $meta_value, $delete_all ); 1006 } 1007 1008 remove_filter( 'query', 'bp_xprofile_filter_meta_query' ); 1009 remove_filter( 'query', 'bp_filter_metaid_column_name' ); 1010 1011 return $retval; 1012 } 1013 1014 /** 1015 * Get a piece of xprofile metadata. 1016 * 1017 * Note that the default value of $single is true, unlike in the case of the 1018 * underlying get_metadata() function. This is for backward compatibility. 1019 * 1020 * @since 1.5.0 1021 * 1022 * @param int $object_id ID of the object the metadata belongs to. 1023 * @param string $object_type Type of object. 'group', 'field', or 'data'. 1024 * @param string $meta_key Key of the metadata being fetched. If omitted, all 1025 * metadata for the object will be retrieved. 1026 * @param bool $single Optional. If true, return only the first value of the 1027 * specified meta_key. This parameter has no effect if meta_key is not 1028 * specified. Default: true. 1029 * @return mixed An array of values if `$single` is false. 1030 * The value of the meta field if `$single` is true. 1031 * False for an invalid `$object_type` (one of `group`, `field`, `data`). 1032 * False for an invalid `$object_id` (non-numeric, zero, or negative value), 1033 * or if `$meta_type` is not specified. 1034 * An empty string if a valid but non-existing object ID is passed. 1035 */ 1036 function bp_xprofile_get_meta( $object_id, $object_type, $meta_key = '', $single = true ) { 1037 // Sanitize object type. 1038 if ( ! in_array( $object_type, array( 'group', 'field', 'data' ) ) ) { 1039 return false; 1040 } 1041 1042 add_filter( 'query', 'bp_filter_metaid_column_name' ); 1043 add_filter( 'query', 'bp_xprofile_filter_meta_query' ); 1044 $retval = get_metadata( 'xprofile_' . $object_type, $object_id, $meta_key, $single ); 1045 remove_filter( 'query', 'bp_filter_metaid_column_name' ); 1046 remove_filter( 'query', 'bp_xprofile_filter_meta_query' ); 1047 1048 return $retval; 1049 } 1050 1051 /** 1052 * Update a piece of xprofile metadata. 1053 * 1054 * @since 1.5.0 1055 * 1056 * @param int $object_id ID of the object the metadata belongs to. 1057 * @param string $object_type Type of object. 'group', 'field', or 'data'. 1058 * @param string $meta_key Key of the metadata being updated. 1059 * @param string $meta_value Value of the metadata being updated. 1060 * @param mixed $prev_value Optional. If specified, only update existing 1061 * metadata entries with the specified value. 1062 * Otherwise update all entries. 1063 * @return bool|int Returns false on failure. On successful update of existing 1064 * metadata, returns true. On successful creation of new metadata, 1065 * returns the integer ID of the new metadata row. 1066 */ 1067 function bp_xprofile_update_meta( $object_id, $object_type, $meta_key, $meta_value, $prev_value = '' ) { 1068 add_filter( 'query', 'bp_filter_metaid_column_name' ); 1069 add_filter( 'query', 'bp_xprofile_filter_meta_query' ); 1070 $retval = update_metadata( 'xprofile_' . $object_type, $object_id, $meta_key, $meta_value, $prev_value ); 1071 remove_filter( 'query', 'bp_xprofile_filter_meta_query' ); 1072 remove_filter( 'query', 'bp_filter_metaid_column_name' ); 1073 1074 return $retval; 1075 } 1076 1077 /** 1078 * Add a piece of xprofile metadata. 1079 * 1080 * @since 2.0.0 1081 * 1082 * @param int $object_id ID of the object the metadata belongs to. 1083 * @param string $object_type Type of object. 'group', 'field', or 'data'. 1084 * @param string $meta_key Metadata key. 1085 * @param mixed $meta_value Metadata value. 1086 * @param bool $unique Optional. Whether to enforce a single metadata value 1087 * for the given key. If true, and the object already 1088 * has a value for the key, no change will be made. 1089 * Default false. 1090 * @return int|bool The meta ID on successful update, false on failure. 1091 */ 1092 function bp_xprofile_add_meta( $object_id, $object_type, $meta_key, $meta_value, $unique = false ) { 1093 add_filter( 'query', 'bp_filter_metaid_column_name' ); 1094 add_filter( 'query', 'bp_xprofile_filter_meta_query' ); 1095 $retval = add_metadata( 'xprofile_' . $object_type , $object_id, $meta_key, $meta_value, $unique ); 1096 remove_filter( 'query', 'bp_filter_metaid_column_name' ); 1097 remove_filter( 'query', 'bp_xprofile_filter_meta_query' ); 1098 1099 return $retval; 1100 } 1101 1102 /** 1103 * Updates the fieldgroup metadata. 1104 * 1105 * @since 1.5.0 1106 * 1107 * @param int $field_group_id Group ID for the group field belongs to. 1108 * @param string $meta_key Meta key to update. 1109 * @param string $meta_value Meta value to update to. 1110 * @return bool|int 1111 */ 1112 function bp_xprofile_update_fieldgroup_meta( $field_group_id, $meta_key, $meta_value ) { 1113 return bp_xprofile_update_meta( $field_group_id, 'group', $meta_key, $meta_value ); 1114 } 1115 1116 /** 1117 * Updates the field metadata. 1118 * 1119 * @since 1.5.0 1120 * 1121 * @param int $field_id Field ID to update. 1122 * @param string $meta_key Meta key to update. 1123 * @param string $meta_value Meta value to update to. 1124 * @return bool|int 1125 */ 1126 function bp_xprofile_update_field_meta( $field_id, $meta_key, $meta_value ) { 1127 return bp_xprofile_update_meta( $field_id, 'field', $meta_key, $meta_value ); 1128 } 1129 1130 /** 1131 * Updates the fielddata metadata. 1132 * 1133 * @since 1.5.0 1134 * 1135 * @param int $field_data_id Field ID to update. 1136 * @param string $meta_key Meta key to update. 1137 * @param string $meta_value Meta value to update to. 1138 * @return bool|int 1139 */ 1140 function bp_xprofile_update_fielddata_meta( $field_data_id, $meta_key, $meta_value ) { 1141 return bp_xprofile_update_meta( $field_data_id, 'data', $meta_key, $meta_value ); 1142 } 1143 1144 /** 1145 * Return the field ID for the Full Name xprofile field. 1146 * 1147 * @since 2.0.0 1148 * 1149 * @return int Field ID. 1150 */ 1151 function bp_xprofile_fullname_field_id() { 1152 $id = wp_cache_get( 'fullname_field_id', 'bp_xprofile' ); 1153 1154 if ( false === $id ) { 1155 global $wpdb; 1156 1157 $bp = buddypress(); 1158 $id = $wpdb->get_var( $wpdb->prepare( "SELECT id FROM {$bp->profile->table_name_fields} WHERE name = %s", addslashes( bp_xprofile_fullname_field_name() ) ) ); 1159 1160 wp_cache_set( 'fullname_field_id', $id, 'bp_xprofile' ); 1161 } 1162 1163 return absint( $id ); 1164 } 1165 1166 /** 1167 * Return the field name for the Full Name xprofile field. 1168 * 1169 * @since 1.5.0 1170 * 1171 * @return string The field name. 1172 */ 1173 function bp_xprofile_fullname_field_name() { 1174 1175 /** 1176 * Filters the field name for the Full Name xprofile field. 1177 * 1178 * @since 1.5.0 1179 * 1180 * @param string $value BP_XPROFILE_FULLNAME_FIELD_NAME Full name field constant. 1181 */ 1182 return apply_filters( 'bp_xprofile_fullname_field_name', BP_XPROFILE_FULLNAME_FIELD_NAME ); 1183 } 1184 1185 /** 1186 * Is rich text enabled for this profile field? 1187 * 1188 * By default, rich text is enabled for textarea fields and disabled for all other field types. 1189 * 1190 * @since 2.4.0 1191 * 1192 * @param int|null $field_id Optional. Default current field ID. 1193 * @return bool 1194 */ 1195 function bp_xprofile_is_richtext_enabled_for_field( $field_id = null ) { 1196 if ( ! $field_id ) { 1197 $field_id = bp_get_the_profile_field_id(); 1198 } 1199 1200 $field = xprofile_get_field( $field_id, null, false ); 1201 1202 $enabled = false; 1203 if ( $field instanceof BP_XProfile_Field ) { 1204 $enabled = (bool) $field->type_obj->supports_richtext; 1205 } 1206 1207 /** 1208 * Filters whether richtext is enabled for the given field. 1209 * 1210 * @since 2.4.0 1211 * 1212 * @param bool $enabled True if richtext is enabled for the field, otherwise false. 1213 * @param int $field_id ID of the field. 1214 */ 1215 return apply_filters( 'bp_xprofile_is_richtext_enabled_for_field', $enabled, $field_id ); 1216 } 1217 1218 /** 1219 * Get visibility levels out of the $bp global. 1220 * 1221 * @since 1.6.0 1222 * 1223 * @return array 1224 */ 1225 function bp_xprofile_get_visibility_levels() { 1226 1227 /** 1228 * Filters the visibility levels out of the $bp global. 1229 * 1230 * @since 1.6.0 1231 * 1232 * @param array $visibility_levels Array of visibility levels. 1233 */ 1234 return apply_filters( 'bp_xprofile_get_visibility_levels', buddypress()->profile->visibility_levels ); 1235 } 1236 1237 /** 1238 * Get the ids of fields that are hidden for this displayed/loggedin user pair. 1239 * 1240 * This is the function primarily responsible for profile field visibility. It works by determining 1241 * the relationship between the displayed_user (ie the profile owner) and the current_user (ie the 1242 * profile viewer). Then, based on that relationship, we query for the set of fields that should 1243 * be excluded from the profile loop. 1244 * 1245 * @since 1.6.0 1246 * 1247 * @see BP_XProfile_Group::get() 1248 * or if you have added your own custom levels. 1249 * 1250 * @param int $displayed_user_id The id of the user the profile fields belong to. 1251 * @param int $current_user_id The id of the user viewing the profile. 1252 * @return array An array of field ids that should be excluded from the profile query 1253 */ 1254 function bp_xprofile_get_hidden_fields_for_user( $displayed_user_id = 0, $current_user_id = 0 ) { 1255 if ( !$displayed_user_id ) { 1256 $displayed_user_id = bp_displayed_user_id(); 1257 } 1258 1259 if ( !$displayed_user_id ) { 1260 return array(); 1261 } 1262 1263 if ( !$current_user_id ) { 1264 $current_user_id = bp_loggedin_user_id(); 1265 } 1266 1267 // @todo - This is where you'd swap out for current_user_can() checks. 1268 $hidden_levels = bp_xprofile_get_hidden_field_types_for_user( $displayed_user_id, $current_user_id ); 1269 $hidden_fields = bp_xprofile_get_fields_by_visibility_levels( $displayed_user_id, $hidden_levels ); 1270 1271 /** 1272 * Filters the ids of fields that are hidden for this displayed/loggedin user pair. 1273 * 1274 * @since 1.6.0 1275 * 1276 * @param array $hidden_fields Array of hidden fields for the displayed/logged in user. 1277 * @param int $displayed_user_id ID of the displayed user. 1278 * @param int $current_user_id ID of the current user. 1279 */ 1280 return apply_filters( 'bp_xprofile_get_hidden_fields_for_user', $hidden_fields, $displayed_user_id, $current_user_id ); 1281 } 1282 1283 /** 1284 * Get the visibility levels that should be hidden for this user pair. 1285 * 1286 * Field visibility is determined based on the relationship between the 1287 * logged-in user, the displayed user, and the visibility setting for the 1288 * current field. (See bp_xprofile_get_hidden_fields_for_user().) This 1289 * utility function speeds up this matching by fetching the visibility levels 1290 * that should be hidden for the current user pair. 1291 * 1292 * @since 1.8.2 1293 * 1294 * @see bp_xprofile_get_hidden_fields_for_user() 1295 * 1296 * @param int $displayed_user_id The id of the user the profile fields belong to. 1297 * @param int $current_user_id The id of the user viewing the profile. 1298 * @return array An array of visibility levels hidden to the current user. 1299 */ 1300 function bp_xprofile_get_hidden_field_types_for_user( $displayed_user_id = 0, $current_user_id = 0 ) { 1301 1302 // Current user is logged in. 1303 if ( ! empty( $current_user_id ) ) { 1304 1305 // Nothing's private when viewing your own profile, or when the 1306 // current user is an admin. 1307 if ( $displayed_user_id == $current_user_id || bp_current_user_can( 'bp_moderate' ) ) { 1308 $hidden_levels = array(); 1309 1310 // If the current user and displayed user are friends, show all. 1311 } elseif ( bp_is_active( 'friends' ) && friends_check_friendship( $displayed_user_id, $current_user_id ) ) { 1312 $hidden_levels = array( 'adminsonly', ); 1313 1314 // Current user is logged in but not friends, so exclude friends-only. 1315 } else { 1316 $hidden_levels = array( 'friends', 'adminsonly', ); 1317 } 1318 1319 // Current user is not logged in, so exclude friends-only, loggedin, and adminsonly. 1320 } else { 1321 $hidden_levels = array( 'friends', 'loggedin', 'adminsonly', ); 1322 } 1323 1324 /** 1325 * Filters the visibility levels that should be hidden for this user pair. 1326 * 1327 * @since 2.0.0 1328 * 1329 * @param array $hidden_fields Array of hidden fields for the displayed/logged in user. 1330 * @param int $displayed_user_id ID of the displayed user. 1331 * @param int $current_user_id ID of the current user. 1332 */ 1333 return apply_filters( 'bp_xprofile_get_hidden_field_types_for_user', $hidden_levels, $displayed_user_id, $current_user_id ); 1334 } 1335 1336 /** 1337 * Fetch an array of the xprofile fields that a given user has marked with certain visibility levels. 1338 * 1339 * @since 1.6.0 1340 * 1341 * @see bp_xprofile_get_hidden_fields_for_user() 1342 * 1343 * @param int $user_id The id of the profile owner. 1344 * @param array $levels An array of visibility levels ('public', 'friends', 'loggedin', 'adminsonly' etc) to be 1345 * checked against. 1346 * @return array $field_ids The fields that match the requested visibility levels for the given user. 1347 */ 1348 function bp_xprofile_get_fields_by_visibility_levels( $user_id, $levels = array() ) { 1349 if ( !is_array( $levels ) ) { 1350 $levels = (array)$levels; 1351 } 1352 1353 $user_visibility_levels = (array) bp_get_user_meta( $user_id, 'bp_xprofile_visibility_levels', true ); 1354 1355 // Parse the user-provided visibility levels with the default levels, which may take 1356 // precedence. 1357 $default_visibility_levels = BP_XProfile_Group::fetch_default_visibility_levels(); 1358 1359 foreach( (array) $default_visibility_levels as $d_field_id => $defaults ) { 1360 // If the admin has forbidden custom visibility levels for this field, replace 1361 // the user-provided setting with the default specified by the admin. 1362 if ( isset( $defaults['allow_custom'] ) && isset( $defaults['default'] ) && 'disabled' == $defaults['allow_custom'] ) { 1363 $user_visibility_levels[$d_field_id] = $defaults['default']; 1364 } 1365 } 1366 1367 $field_ids = array(); 1368 foreach( $user_visibility_levels as $field_id => $field_visibility ) { 1369 if ( in_array( $field_visibility, $levels ) ) { 1370 $field_ids[] = $field_id; 1371 } 1372 } 1373 1374 // Never allow the fullname field to be excluded. 1375 if ( in_array( 1, $field_ids ) ) { 1376 $key = array_search( 1, $field_ids ); 1377 unset( $field_ids[$key] ); 1378 } 1379 1380 return $field_ids; 1381 } 1382 1383 /** 1384 * Formats datebox field values passed through a POST request. 1385 * 1386 * @since 2.8.0 1387 * 1388 * @param int $field_id The id of the current field being looped through. 1389 * @return void This function only changes the global $_POST that should contain 1390 * the datebox data. 1391 */ 1392 function bp_xprofile_maybe_format_datebox_post_data( $field_id ) { 1393 if ( ! isset( $_POST['field_' . $field_id] ) ) { 1394 if ( ! empty( $_POST['field_' . $field_id . '_day'] ) && ! empty( $_POST['field_' . $field_id . '_month'] ) && ! empty( $_POST['field_' . $field_id . '_year'] ) ) { 1395 // Concatenate the values. 1396 $date_value = $_POST['field_' . $field_id . '_day'] . ' ' . $_POST['field_' . $field_id . '_month'] . ' ' . $_POST['field_' . $field_id . '_year']; 1397 1398 // Check that the concatenated value can be turned into a timestamp. 1399 if ( $timestamp = strtotime( $date_value ) ) { 1400 // Add the timestamp to the global $_POST that should contain the datebox data. 1401 $_POST['field_' . $field_id] = date( 'Y-m-d H:i:s', $timestamp ); 1402 } 1403 } 1404 } 1405 } 1406 1407 /** 1408 * Finds and exports personal data associated with an email address from the XProfile tables. 1409 * 1410 * @since 4.0.0 1411 * 1412 * @param string $email_address The users email address. 1413 * @return array An array of personal data. 1414 */ 1415 function bp_xprofile_personal_data_exporter( $email_address ) { 1416 $email_address = trim( $email_address ); 1417 1418 $data_to_export = array(); 1419 1420 $user = get_user_by( 'email', $email_address ); 1421 1422 if ( ! $user ) { 1423 return array( 1424 'data' => array(), 1425 'done' => true, 1426 ); 1427 } 1428 1429 $user_data_to_export = array(); 1430 1431 $user_profile_data = BP_XProfile_ProfileData::get_all_for_user( $user->ID ); 1432 foreach ( $user_profile_data as $field_name => $field ) { 1433 // Skip non-array fields, which don't belong to XProfile. 1434 if ( ! is_array( $field ) ) { 1435 continue; 1436 } 1437 1438 // Re-pull the data so that BuddyPress formats and sanitizes properly. 1439 $value = xprofile_get_field_data( $field['field_id'], $user->ID, 'comma' ); 1440 $user_data_to_export[] = array( 1441 'name' => $field_name, 1442 'value' => $value, 1443 ); 1444 } 1445 1446 $data_to_export[] = array( 1447 'group_id' => 'bp_xprofile', 1448 'group_label' => __( 'Extended Profile Data', 'buddypress' ), 1449 'item_id' => "bp-xprofile-{$user->ID}", 1450 'data' => $user_data_to_export, 1451 ); 1452 1453 return array( 1454 'data' => $data_to_export, 1455 'done' => true, 1456 ); 1457 } 1458 1459 /** 1460 * Returns the list of supporterd WordPress field meta keys. 1461 * 1462 * @since 8.0.0 1463 * 1464 * @return string[] List of supported WordPress user keys. 1465 */ 1466 function bp_xprofile_get_wp_user_keys() { 1467 return array_merge( 1468 array( 'first_name', 'last_name', 'user_url', 'description' ), 1469 array_keys( wp_get_user_contact_methods() ) 1470 ); 1471 } 1472 1473 /** 1474 * Returns the signup field IDs. 1475 * 1476 * @since 8.0.0 1477 * 1478 * @return int[] The signup field IDs. 1479 */ 1480 function bp_xprofile_get_signup_field_ids() { 1481 $signup_field_ids = wp_cache_get( 'signup_fields', 'bp_xprofile' ); 1482 1483 if ( ! $signup_field_ids ) { 1484 global $wpdb; 1485 $bp = buddypress(); 1486 1487 $signup_field_ids = $wpdb->get_col( "SELECT object_id FROM {$bp->profile->table_name_meta} WHERE object_type = 'field' AND meta_key = 'signup_position' ORDER BY CONVERT(meta_value, SIGNED) ASC" ); 1488 1489 wp_cache_set( 'signup_fields', $signup_field_ids, 'bp_xprofile' ); 1490 } 1491 1492 return array_map( 'intval', $signup_field_ids ); 1493 } 1494 1495 /** 1496 * Returns xProfile loop's signup arguments. 1497 * 1498 * @since 8.0.0 1499 * 1500 * @param array $extra Optional extra arguments. 1501 * @return array The xProfile loop's signup arguments. 1502 */ 1503 function bp_xprofile_signup_args( $extra = array() ) { 1504 $signup_fields = (array) bp_xprofile_get_signup_field_ids(); 1505 $default_args = array( 1506 'fetch_fields' => true, 1507 'fetch_field_data' => false, 1508 ); 1509 1510 // No signup fields? Let's bring back primary group. 1511 if ( ! $signup_fields && bp_is_register_page() ) { 1512 $default_args['profile_group_id'] = 1; 1513 } else { 1514 $default_args['signup_fields_only'] = true; 1515 } 1516 1517 return array_merge( $default_args, $extra ); 1518 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Sun Dec 22 01:00:54 2024 | Cross-referenced by PHPXref 0.7.1 |