/bp-xprofile/bp-xprofile-functions.php

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