[ 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 field_types whitelist.
 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 whitelist.
 456      if ( $field_type_obj->supports_options ) {
 457          $field_type_obj->set_whitelist_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 visibity 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 whitelist.
 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   * Setup the avatar upload directory for a user.
 710   *
 711   * @since 1.0.0
 712   *
 713   * @package BuddyPress Core
 714   *
 715   * @param string $directory The root directory name. Optional.
 716   * @param int    $user_id   The user ID. Optional.
 717   * @return array Array containing the path, URL, and other helpful settings.
 718   */
 719  function xprofile_avatar_upload_dir( $directory = 'avatars', $user_id = 0 ) {
 720  
 721      // Use displayed user if no user ID was passed.
 722      if ( empty( $user_id ) ) {
 723          $user_id = bp_displayed_user_id();
 724      }
 725  
 726      // Failsafe against accidentally nooped $directory parameter.
 727      if ( empty( $directory ) ) {
 728          $directory = 'avatars';
 729      }
 730  
 731      $path      = bp_core_avatar_upload_path() . '/' . $directory. '/' . $user_id;
 732      $newbdir   = $path;
 733      $newurl    = bp_core_avatar_url() . '/' . $directory. '/' . $user_id;
 734      $newburl   = $newurl;
 735      $newsubdir = '/' . $directory. '/' . $user_id;
 736  
 737      /**
 738       * Filters the avatar upload directory for a user.
 739       *
 740       * @since 1.1.0
 741       *
 742       * @param array $value Array containing the path, URL, and other helpful settings.
 743       */
 744      return apply_filters( 'xprofile_avatar_upload_dir', array(
 745          'path'    => $path,
 746          'url'     => $newurl,
 747          'subdir'  => $newsubdir,
 748          'basedir' => $newbdir,
 749          'baseurl' => $newburl,
 750          'error'   => false
 751      ) );
 752  }
 753  
 754  /**
 755   * When search_terms are passed to BP_User_Query, search against xprofile fields.
 756   *
 757   * @since 2.0.0
 758   *
 759   * @param array         $sql   Clauses in the user_id SQL query.
 760   * @param BP_User_Query $query User query object.
 761   * @return array
 762   */
 763  function bp_xprofile_bp_user_query_search( $sql, BP_User_Query $query ) {
 764      global $wpdb;
 765  
 766      if ( empty( $query->query_vars['search_terms'] ) || empty( $sql['where']['search'] ) ) {
 767          return $sql;
 768      }
 769  
 770      $bp = buddypress();
 771  
 772      $search_terms_clean = bp_esc_like( wp_kses_normalize_entities( $query->query_vars['search_terms'] ) );
 773  
 774      if ( $query->query_vars['search_wildcard'] === 'left' ) {
 775          $search_terms_nospace = '%' . $search_terms_clean;
 776          $search_terms_space   = '%' . $search_terms_clean . ' %';
 777      } elseif ( $query->query_vars['search_wildcard'] === 'right' ) {
 778          $search_terms_nospace =        $search_terms_clean . '%';
 779          $search_terms_space   = '% ' . $search_terms_clean . '%';
 780      } else {
 781          $search_terms_nospace = '%' . $search_terms_clean . '%';
 782          $search_terms_space   = '%' . $search_terms_clean . '%';
 783      }
 784  
 785      // Combine the core search (against wp_users) into a single OR clause
 786      // with the xprofile_data search.
 787      $matched_user_ids = $wpdb->get_col( $wpdb->prepare(
 788          "SELECT user_id FROM {$bp->profile->table_name_data} WHERE value LIKE %s OR value LIKE %s",
 789          $search_terms_nospace,
 790          $search_terms_space
 791      ) );
 792  
 793      if ( ! empty( $matched_user_ids ) ) {
 794          $search_core     = $sql['where']['search'];
 795          $search_combined = " ( u.{$query->uid_name} IN (" . implode(',', $matched_user_ids) . ") OR {$search_core} )";
 796          $sql['where']['search'] = $search_combined;
 797      }
 798  
 799      return $sql;
 800  }
 801  add_action( 'bp_user_query_uid_clauses', 'bp_xprofile_bp_user_query_search', 10, 2 );
 802  
 803  /**
 804   * Syncs Xprofile data to the standard built in WordPress profile data.
 805   *
 806   * @since 1.0.0
 807   *
 808   * @param int $user_id ID of the user to sync.
 809   * @return bool
 810   */
 811  function xprofile_sync_wp_profile( $user_id = 0 ) {
 812  
 813      // Bail if profile syncing is disabled.
 814      if ( bp_disable_profile_sync() ) {
 815          return true;
 816      }
 817  
 818      if ( empty( $user_id ) ) {
 819          $user_id = bp_loggedin_user_id();
 820      }
 821  
 822      if ( empty( $user_id ) ) {
 823          return false;
 824      }
 825  
 826      $fullname = xprofile_get_field_data( bp_xprofile_fullname_field_id(), $user_id );
 827      $space    = strpos( $fullname, ' ' );
 828  
 829      if ( false === $space ) {
 830          $firstname = $fullname;
 831          $lastname = '';
 832      } else {
 833          $firstname = substr( $fullname, 0, $space );
 834          $lastname = trim( substr( $fullname, $space, strlen( $fullname ) ) );
 835      }
 836  
 837      bp_update_user_meta( $user_id, 'nickname',   $fullname  );
 838      bp_update_user_meta( $user_id, 'first_name', $firstname );
 839      bp_update_user_meta( $user_id, 'last_name',  $lastname  );
 840  
 841      wp_update_user( array( 'ID' => $user_id, 'display_name' => $fullname ) );
 842  }
 843  add_action( 'bp_core_signup_user',      'xprofile_sync_wp_profile' );
 844  add_action( 'bp_core_activated_user',   'xprofile_sync_wp_profile' );
 845  
 846  /**
 847   * Syncs the standard built in WordPress profile data to XProfile.
 848   *
 849   * @since 1.2.4
 850   *
 851   * @param object $errors Array of errors. Passed by reference.
 852   * @param bool   $update Whether or not being upated.
 853   * @param object $user   User object whose profile is being synced. Passed by reference.
 854   */
 855  function xprofile_sync_bp_profile( &$errors, $update, &$user ) {
 856  
 857      // Bail if profile syncing is disabled.
 858      if ( bp_disable_profile_sync() || ! $update || $errors->get_error_codes() ) {
 859          return;
 860      }
 861  
 862      xprofile_set_field_data( bp_xprofile_fullname_field_id(), $user->ID, $user->display_name );
 863  }
 864  add_action( 'user_profile_update_errors', 'xprofile_sync_bp_profile', 10, 3 );
 865  
 866  /**
 867   * Update the WP display, last, and first name fields when the xprofile display name field is updated.
 868   *
 869   * @since 3.0.0
 870   *
 871   * @param BP_XProfile_ProfileData $data Current instance of the profile data being saved.
 872   */
 873  function xprofile_sync_wp_profile_on_single_field_set( $data ) {
 874  
 875      if ( bp_xprofile_fullname_field_id() !== $data->field_id ) {
 876          return;
 877      }
 878  
 879      xprofile_sync_wp_profile( $data->user_id );
 880  }
 881  add_action( 'xprofile_data_after_save', 'xprofile_sync_wp_profile_on_single_field_set' );
 882  
 883  /**
 884   * When a user is deleted, we need to clean up the database and remove all the
 885   * profile data from each table. Also we need to clean anything up in the
 886   * usermeta table that this component uses.
 887   *
 888   * @since 1.0.0
 889   *
 890   * @param int $user_id The ID of the deleted user.
 891   */
 892  function xprofile_remove_data( $user_id ) {
 893      BP_XProfile_ProfileData::delete_data_for_user( $user_id );
 894  }
 895  add_action( 'wpmu_delete_user',  'xprofile_remove_data' );
 896  add_action( 'delete_user',       'xprofile_remove_data' );
 897  add_action( 'bp_make_spam_user', 'xprofile_remove_data' );
 898  
 899  /*** XProfile Meta ****************************************************/
 900  
 901  /**
 902   * Delete a piece of xprofile metadata.
 903   *
 904   * @since 1.5.0
 905   *
 906   * @param int         $object_id   ID of the object the metadata belongs to.
 907   * @param string      $object_type Type of object. 'group', 'field', or 'data'.
 908   * @param string|bool $meta_key    Key of the metadata being deleted. If omitted, all
 909   *                                 metadata for the object will be deleted.
 910   * @param mixed       $meta_value  Optional. If provided, only metadata that matches
 911   *                                 the value will be permitted.
 912   * @param bool        $delete_all  Optional. If true, delete matching metadata entries
 913   *                                 for all objects, ignoring the specified object_id. Otherwise, only
 914   *                                 delete matching metadata entries for the specified object.
 915   *                                 Default: false.
 916   * @return bool True on success, false on failure.
 917   */
 918  function bp_xprofile_delete_meta( $object_id, $object_type, $meta_key = false, $meta_value = false, $delete_all = false ) {
 919      global $wpdb;
 920  
 921      // Sanitize object type.
 922      if ( ! in_array( $object_type, array( 'group', 'field', 'data' ) ) ) {
 923          return false;
 924      }
 925  
 926      // Legacy - if no meta_key is passed, delete all for the item.
 927      if ( empty( $meta_key ) ) {
 928          $table_key  = 'xprofile_' . $object_type . 'meta';
 929          $table_name = $wpdb->{$table_key};
 930          $keys = $wpdb->get_col( $wpdb->prepare( "SELECT meta_key FROM {$table_name} WHERE object_type = %s AND object_id = %d", $object_type, $object_id ) );
 931  
 932          // Force delete_all to false if deleting all for object.
 933          $delete_all = false;
 934      } else {
 935          $keys = array( $meta_key );
 936      }
 937  
 938      add_filter( 'query', 'bp_filter_metaid_column_name' );
 939      add_filter( 'query', 'bp_xprofile_filter_meta_query' );
 940  
 941      $retval = false;
 942      foreach ( $keys as $key ) {
 943          $retval = delete_metadata( 'xprofile_' . $object_type, $object_id, $key, $meta_value, $delete_all );
 944      }
 945  
 946      remove_filter( 'query', 'bp_xprofile_filter_meta_query' );
 947      remove_filter( 'query', 'bp_filter_metaid_column_name' );
 948  
 949      return $retval;
 950  }
 951  
 952  /**
 953   * Get a piece of xprofile metadata.
 954   *
 955   * Note that the default value of $single is true, unlike in the case of the
 956   * underlying get_metadata() function. This is for backward compatibility.
 957   *
 958   * @since 1.5.0
 959   *
 960   * @param int    $object_id   ID of the object the metadata belongs to.
 961   * @param string $object_type Type of object. 'group', 'field', or 'data'.
 962   * @param string $meta_key    Key of the metadata being fetched. If omitted, all
 963   *                            metadata for the object will be retrieved.
 964   * @param bool   $single      Optional. If true, return only the first value of the
 965   *                            specified meta_key. This parameter has no effect if meta_key is not
 966   *                            specified. Default: true.
 967   * @return mixed Meta value if found. False on failure.
 968   */
 969  function bp_xprofile_get_meta( $object_id, $object_type, $meta_key = '', $single = true ) {
 970      // Sanitize object type.
 971      if ( ! in_array( $object_type, array( 'group', 'field', 'data' ) ) ) {
 972          return false;
 973      }
 974  
 975      add_filter( 'query', 'bp_filter_metaid_column_name' );
 976      add_filter( 'query', 'bp_xprofile_filter_meta_query' );
 977      $retval = get_metadata( 'xprofile_' . $object_type, $object_id, $meta_key, $single );
 978      remove_filter( 'query', 'bp_filter_metaid_column_name' );
 979      remove_filter( 'query', 'bp_xprofile_filter_meta_query' );
 980  
 981      return $retval;
 982  }
 983  
 984  /**
 985   * Update a piece of xprofile metadata.
 986   *
 987   * @since 1.5.0
 988   *
 989   * @param int    $object_id   ID of the object the metadata belongs to.
 990   * @param string $object_type Type of object. 'group', 'field', or 'data'.
 991   * @param string $meta_key    Key of the metadata being updated.
 992   * @param string $meta_value  Value of the metadata being updated.
 993   * @param mixed  $prev_value  Optional. If specified, only update existing
 994   *                            metadata entries with the specified value.
 995   *                            Otherwise update all entries.
 996   * @return bool|int Returns false on failure. On successful update of existing
 997   *                  metadata, returns true. On successful creation of new metadata,
 998   *                  returns the integer ID of the new metadata row.
 999   */
1000  function bp_xprofile_update_meta( $object_id, $object_type, $meta_key, $meta_value, $prev_value = '' ) {
1001      add_filter( 'query', 'bp_filter_metaid_column_name' );
1002      add_filter( 'query', 'bp_xprofile_filter_meta_query' );
1003      $retval = update_metadata( 'xprofile_' . $object_type, $object_id, $meta_key, $meta_value, $prev_value );
1004      remove_filter( 'query', 'bp_xprofile_filter_meta_query' );
1005      remove_filter( 'query', 'bp_filter_metaid_column_name' );
1006  
1007      return $retval;
1008  }
1009  
1010  /**
1011   * Add a piece of xprofile metadata.
1012   *
1013   * @since 2.0.0
1014   *
1015   * @param int    $object_id   ID of the object the metadata belongs to.
1016   * @param string $object_type Type of object. 'group', 'field', or 'data'.
1017   * @param string $meta_key    Metadata key.
1018   * @param mixed  $meta_value  Metadata value.
1019   * @param bool   $unique      Optional. Whether to enforce a single metadata value
1020   *                            for the given key. If true, and the object already
1021   *                            has a value for the key, no change will be made.
1022   *                            Default false.
1023   * @return int|bool The meta ID on successful update, false on failure.
1024   */
1025  function bp_xprofile_add_meta( $object_id, $object_type, $meta_key, $meta_value, $unique = false ) {
1026      add_filter( 'query', 'bp_filter_metaid_column_name' );
1027      add_filter( 'query', 'bp_xprofile_filter_meta_query' );
1028      $retval = add_metadata( 'xprofile_' . $object_type , $object_id, $meta_key, $meta_value, $unique );
1029      remove_filter( 'query', 'bp_filter_metaid_column_name' );
1030      remove_filter( 'query', 'bp_xprofile_filter_meta_query' );
1031  
1032      return $retval;
1033  }
1034  
1035  /**
1036   * Updates the fieldgroup metadata.
1037   *
1038   * @since 1.5.0
1039   *
1040   * @param int    $field_group_id Group ID for the group field belongs to.
1041   * @param string $meta_key       Meta key to update.
1042   * @param string $meta_value     Meta value to update to.
1043   * @return bool|int
1044   */
1045  function bp_xprofile_update_fieldgroup_meta( $field_group_id, $meta_key, $meta_value ) {
1046      return bp_xprofile_update_meta( $field_group_id, 'group', $meta_key, $meta_value );
1047  }
1048  
1049  /**
1050   * Updates the field metadata.
1051   *
1052   * @since 1.5.0
1053   *
1054   * @param int    $field_id   Field ID to update.
1055   * @param string $meta_key   Meta key to update.
1056   * @param string $meta_value Meta value to update to.
1057   * @return bool|int
1058   */
1059  function bp_xprofile_update_field_meta( $field_id, $meta_key, $meta_value ) {
1060      return bp_xprofile_update_meta( $field_id, 'field', $meta_key, $meta_value );
1061  }
1062  
1063  /**
1064   * Updates the fielddata metadata.
1065   *
1066   * @since 1.5.0
1067   *
1068   * @param int    $field_data_id Field ID to update.
1069   * @param string $meta_key      Meta key to update.
1070   * @param string $meta_value    Meta value to update to.
1071   * @return bool|int
1072   */
1073  function bp_xprofile_update_fielddata_meta( $field_data_id, $meta_key, $meta_value ) {
1074      return bp_xprofile_update_meta( $field_data_id, 'data', $meta_key, $meta_value );
1075  }
1076  
1077  /**
1078   * Return the field ID for the Full Name xprofile field.
1079   *
1080   * @since 2.0.0
1081   *
1082   * @return int Field ID.
1083   */
1084  function bp_xprofile_fullname_field_id() {
1085      $id = wp_cache_get( 'fullname_field_id', 'bp_xprofile' );
1086  
1087      if ( false === $id ) {
1088          global $wpdb;
1089  
1090          $bp = buddypress();
1091          $id = $wpdb->get_var( $wpdb->prepare( "SELECT id FROM {$bp->profile->table_name_fields} WHERE name = %s", addslashes( bp_xprofile_fullname_field_name() ) ) );
1092  
1093          wp_cache_set( 'fullname_field_id', $id, 'bp_xprofile' );
1094      }
1095  
1096      return absint( $id );
1097  }
1098  
1099  /**
1100   * Return the field name for the Full Name xprofile field.
1101   *
1102   * @since 1.5.0
1103   *
1104   * @return string The field name.
1105   */
1106  function bp_xprofile_fullname_field_name() {
1107  
1108      /**
1109       * Filters the field name for the Full Name xprofile field.
1110       *
1111       * @since 1.5.0
1112       *
1113       * @param string $value BP_XPROFILE_FULLNAME_FIELD_NAME Full name field constant.
1114       */
1115      return apply_filters( 'bp_xprofile_fullname_field_name', BP_XPROFILE_FULLNAME_FIELD_NAME );
1116  }
1117  
1118  /**
1119   * Is rich text enabled for this profile field?
1120   *
1121   * By default, rich text is enabled for textarea fields and disabled for all other field types.
1122   *
1123   * @since 2.4.0
1124   *
1125   * @param int|null $field_id Optional. Default current field ID.
1126   * @return bool
1127   */
1128  function bp_xprofile_is_richtext_enabled_for_field( $field_id = null ) {
1129      if ( ! $field_id ) {
1130          $field_id = bp_get_the_profile_field_id();
1131      }
1132  
1133      $field = xprofile_get_field( $field_id );
1134  
1135      $enabled = false;
1136      if ( $field instanceof BP_XProfile_Field ) {
1137          $enabled = (bool) $field->type_obj->supports_richtext;
1138      }
1139  
1140      /**
1141       * Filters whether richtext is enabled for the given field.
1142       *
1143       * @since 2.4.0
1144       *
1145       * @param bool $enabled  True if richtext is enabled for the field, otherwise false.
1146       * @param int  $field_id ID of the field.
1147       */
1148      return apply_filters( 'bp_xprofile_is_richtext_enabled_for_field', $enabled, $field_id );
1149  }
1150  
1151  /**
1152   * Get visibility levels out of the $bp global.
1153   *
1154   * @since 1.6.0
1155   *
1156   * @return array
1157   */
1158  function bp_xprofile_get_visibility_levels() {
1159  
1160      /**
1161       * Filters the visibility levels out of the $bp global.
1162       *
1163       * @since 1.6.0
1164       *
1165       * @param array $visibility_levels Array of visibility levels.
1166       */
1167      return apply_filters( 'bp_xprofile_get_visibility_levels', buddypress()->profile->visibility_levels );
1168  }
1169  
1170  /**
1171   * Get the ids of fields that are hidden for this displayed/loggedin user pair.
1172   *
1173   * This is the function primarily responsible for profile field visibility. It works by determining
1174   * the relationship between the displayed_user (ie the profile owner) and the current_user (ie the
1175   * profile viewer). Then, based on that relationship, we query for the set of fields that should
1176   * be excluded from the profile loop.
1177   *
1178   * @since 1.6.0
1179   *
1180   * @see BP_XProfile_Group::get()
1181   *   or if you have added your own custom levels.
1182   *
1183   * @param int $displayed_user_id The id of the user the profile fields belong to.
1184   * @param int $current_user_id   The id of the user viewing the profile.
1185   * @return array An array of field ids that should be excluded from the profile query
1186   */
1187  function bp_xprofile_get_hidden_fields_for_user( $displayed_user_id = 0, $current_user_id = 0 ) {
1188      if ( !$displayed_user_id ) {
1189          $displayed_user_id = bp_displayed_user_id();
1190      }
1191  
1192      if ( !$displayed_user_id ) {
1193          return array();
1194      }
1195  
1196      if ( !$current_user_id ) {
1197          $current_user_id = bp_loggedin_user_id();
1198      }
1199  
1200      // @todo - This is where you'd swap out for current_user_can() checks
1201      $hidden_levels = bp_xprofile_get_hidden_field_types_for_user( $displayed_user_id, $current_user_id );
1202      $hidden_fields = bp_xprofile_get_fields_by_visibility_levels( $displayed_user_id, $hidden_levels );
1203  
1204      /**
1205       * Filters the ids of fields that are hidden for this displayed/loggedin user pair.
1206       *
1207       * @since 1.6.0
1208       *
1209       * @param array $hidden_fields     Array of hidden fields for the displayed/logged in user.
1210       * @param int   $displayed_user_id ID of the displayed user.
1211       * @param int   $current_user_id   ID of the current user.
1212       */
1213      return apply_filters( 'bp_xprofile_get_hidden_fields_for_user', $hidden_fields, $displayed_user_id, $current_user_id );
1214  }
1215  
1216  /**
1217   * Get the visibility levels that should be hidden for this user pair.
1218   *
1219   * Field visibility is determined based on the relationship between the
1220   * logged-in user, the displayed user, and the visibility setting for the
1221   * current field. (See bp_xprofile_get_hidden_fields_for_user().) This
1222   * utility function speeds up this matching by fetching the visibility levels
1223   * that should be hidden for the current user pair.
1224   *
1225   * @since 1.8.2
1226   *
1227   * @see bp_xprofile_get_hidden_fields_for_user()
1228   *
1229   * @param int $displayed_user_id The id of the user the profile fields belong to.
1230   * @param int $current_user_id   The id of the user viewing the profile.
1231   * @return array An array of visibility levels hidden to the current user.
1232   */
1233  function bp_xprofile_get_hidden_field_types_for_user( $displayed_user_id = 0, $current_user_id = 0 ) {
1234  
1235      // Current user is logged in.
1236      if ( ! empty( $current_user_id ) ) {
1237  
1238          // Nothing's private when viewing your own profile, or when the
1239          // current user is an admin.
1240          if ( $displayed_user_id == $current_user_id || bp_current_user_can( 'bp_moderate' ) ) {
1241              $hidden_levels = array();
1242  
1243          // If the current user and displayed user are friends, show all.
1244          } elseif ( bp_is_active( 'friends' ) && friends_check_friendship( $displayed_user_id, $current_user_id ) ) {
1245              $hidden_levels = array( 'adminsonly', );
1246  
1247          // Current user is logged in but not friends, so exclude friends-only.
1248          } else {
1249              $hidden_levels = array( 'friends', 'adminsonly', );
1250          }
1251  
1252      // Current user is not logged in, so exclude friends-only, loggedin, and adminsonly.
1253      } else {
1254          $hidden_levels = array( 'friends', 'loggedin', 'adminsonly', );
1255      }
1256  
1257      /**
1258       * Filters the visibility levels that should be hidden for this user pair.
1259       *
1260       * @since 2.0.0
1261       *
1262       * @param array $hidden_fields     Array of hidden fields for the displayed/logged in user.
1263       * @param int   $displayed_user_id ID of the displayed user.
1264       * @param int   $current_user_id   ID of the current user.
1265       */
1266      return apply_filters( 'bp_xprofile_get_hidden_field_types_for_user', $hidden_levels, $displayed_user_id, $current_user_id );
1267  }
1268  
1269  /**
1270   * Fetch an array of the xprofile fields that a given user has marked with certain visibility levels.
1271   *
1272   * @since 1.6.0
1273   *
1274   * @see bp_xprofile_get_hidden_fields_for_user()
1275   *
1276   * @param int   $user_id The id of the profile owner.
1277   * @param array $levels  An array of visibility levels ('public', 'friends', 'loggedin', 'adminsonly' etc) to be
1278   *                       checked against.
1279   * @return array $field_ids The fields that match the requested visibility levels for the given user.
1280   */
1281  function bp_xprofile_get_fields_by_visibility_levels( $user_id, $levels = array() ) {
1282      if ( !is_array( $levels ) ) {
1283          $levels = (array)$levels;
1284      }
1285  
1286      $user_visibility_levels = bp_get_user_meta( $user_id, 'bp_xprofile_visibility_levels', true );
1287  
1288      // Parse the user-provided visibility levels with the default levels, which may take
1289      // precedence.
1290      $default_visibility_levels = BP_XProfile_Group::fetch_default_visibility_levels();
1291  
1292      foreach( (array) $default_visibility_levels as $d_field_id => $defaults ) {
1293          // If the admin has forbidden custom visibility levels for this field, replace
1294          // the user-provided setting with the default specified by the admin.
1295          if ( isset( $defaults['allow_custom'] ) && isset( $defaults['default'] ) && 'disabled' == $defaults['allow_custom'] ) {
1296              $user_visibility_levels[$d_field_id] = $defaults['default'];
1297          }
1298      }
1299  
1300      $field_ids = array();
1301      foreach( (array) $user_visibility_levels as $field_id => $field_visibility ) {
1302          if ( in_array( $field_visibility, $levels ) ) {
1303              $field_ids[] = $field_id;
1304          }
1305      }
1306  
1307      // Never allow the fullname field to be excluded.
1308      if ( in_array( 1, $field_ids ) ) {
1309          $key = array_search( 1, $field_ids );
1310          unset( $field_ids[$key] );
1311      }
1312  
1313      return $field_ids;
1314  }
1315  
1316  /**
1317   * Formats datebox field values passed through a POST request.
1318   *
1319   * @since 2.8.0
1320   *
1321   * @param int $field_id The id of the current field being looped through.
1322   * @return void This function only changes the global $_POST that should contain
1323   *              the datebox data.
1324   */
1325  function bp_xprofile_maybe_format_datebox_post_data( $field_id ) {
1326      if ( ! isset( $_POST['field_' . $field_id] ) ) {
1327          if ( ! empty( $_POST['field_' . $field_id . '_day'] ) && ! empty( $_POST['field_' . $field_id . '_month'] ) && ! empty( $_POST['field_' . $field_id . '_year'] ) ) {
1328              // Concatenate the values.
1329              $date_value = $_POST['field_' . $field_id . '_day'] . ' ' . $_POST['field_' . $field_id . '_month'] . ' ' . $_POST['field_' . $field_id . '_year'];
1330  
1331              // Check that the concatenated value can be turned into a timestamp.
1332              if ( $timestamp = strtotime( $date_value ) ) {
1333                  // Add the timestamp to the global $_POST that should contain the datebox data.
1334                  $_POST['field_' . $field_id] = date( 'Y-m-d H:i:s', $timestamp );
1335              }
1336          }
1337      }
1338  }
1339  
1340  /**
1341   * Finds and exports personal data associated with an email address from the XProfile tables.
1342   *
1343   * @since 4.0.0
1344   *
1345   * @param string $email_address  The userss email address.
1346   * @return array An array of personal data.
1347   */
1348  function bp_xprofile_personal_data_exporter( $email_address ) {
1349      $email_address = trim( $email_address );
1350  
1351      $data_to_export = array();
1352  
1353      $user = get_user_by( 'email', $email_address );
1354  
1355      if ( ! $user ) {
1356          return array(
1357              'data' => array(),
1358              'done' => true,
1359          );
1360      }
1361  
1362      $user_data_to_export = array();
1363  
1364      $user_profile_data = BP_XProfile_ProfileData::get_all_for_user( $user->ID );
1365      foreach ( $user_profile_data as $field_name => $field ) {
1366          // Skip non-array fields, which don't belong to XProfile.
1367          if ( ! is_array( $field ) ) {
1368              continue;
1369          }
1370  
1371          // Re-pull the data so that BuddyPress formats and sanitizes properly.
1372          $value = xprofile_get_field_data( $field['field_id'], $user->ID, 'comma' );
1373          $user_data_to_export[] = array(
1374              'name'  => $field_name,
1375              'value' => $value,
1376          );
1377      }
1378  
1379      $data_to_export[] = array(
1380          'group_id'    => 'bp_xprofile',
1381          'group_label' => __( 'Extended Profile Data', 'buddypress' ),
1382          'item_id'     => "bp-xprofile-{$user->ID}",
1383          'data'        => $user_data_to_export,
1384      );
1385  
1386      return array(
1387          'data' => $data_to_export,
1388          'done' => true,
1389      );
1390  }


Generated: Tue Jul 16 01:01:43 2019 Cross-referenced by PHPXref 0.7.1