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