[ Index ]

PHP Cross Reference of BuddyPress

title

Body

[close]

/src/bp-xprofile/ -> bp-xprofile-functions.php (source)

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


Generated: Sun Oct 25 01:01:40 2020 Cross-referenced by PHPXref 0.7.1