/bp-xprofile/bp-xprofile-admin.php

  1. <?php 
  2. /** 
  3. * BuddyPress XProfile Admin. 
  4. * 
  5. * @package BuddyPress 
  6. * @subpackage XProfileAdmin 
  7. * @since 1.0.0 
  8. */ 
  9.  
  10. // Exit if accessed directly. 
  11. defined( 'ABSPATH' ) || exit; 
  12.  
  13. /** 
  14. * Creates the administration interface menus and checks to see if the DB 
  15. * tables are set up. 
  16. * 
  17. * @since 1.0.0 
  18. * 
  19. * @return bool 
  20. */ 
  21. function xprofile_add_admin_menu() { 
  22.  
  23. // Bail if current user cannot moderate community. 
  24. if ( ! bp_current_user_can( 'bp_moderate' ) ) { 
  25. return false; 
  26.  
  27. add_users_page( _x( 'Profile Fields', 'xProfile admin page title', 'buddypress' ), _x( 'Profile Fields', 'Admin Users menu', 'buddypress' ), 'manage_options', 'bp-profile-setup', 'xprofile_admin' ); 
  28. add_action( bp_core_admin_hook(), 'xprofile_add_admin_menu' ); 
  29.  
  30. /** 
  31. * Handles all actions for the admin area for creating, editing and deleting 
  32. * profile groups and fields. 
  33. * 
  34. * @since 1.0.0 
  35. * 
  36. * @param string $message Message to display. 
  37. * @param string $type Type of action to be displayed. 
  38. */ 
  39. function xprofile_admin( $message = '', $type = 'error' ) { 
  40.  
  41. // What mode? 
  42. $mode = ! empty( $_GET['mode'] ) 
  43. ? sanitize_key( $_GET['mode'] ) 
  44. : false; 
  45.  
  46. // Group ID 
  47. $group_id = ! empty( $_GET['group_id'] ) 
  48. ? intval( $_GET['group_id'] ) 
  49. : false; 
  50.  
  51. // Field ID 
  52. $field_id = ! empty( $_GET['field_id'] ) 
  53. ? intval( $_GET['field_id'] ) 
  54. : false; 
  55.  
  56. // Option ID 
  57. $option_id = ! empty( $_GET['option_id'] ) 
  58. ? intval( $_GET['option_id'] ) 
  59. : false; 
  60.  
  61. // Allowed modes 
  62. $allowed_modes = array( 
  63. 'add_group',  
  64. 'edit_group',  
  65. 'delete_group',  
  66. 'add_field',  
  67. 'edit_field',  
  68. 'delete_field',  
  69. 'delete_option' 
  70. ); 
  71.  
  72. // Is an allowed mode 
  73. if ( in_array( $mode, $allowed_modes, true ) ) { 
  74.  
  75. // All group actions 
  76. if ( false !== $group_id ) { 
  77.  
  78. // Add field to group 
  79. if ( 'add_field' == $mode ) { 
  80. xprofile_admin_manage_field( $group_id ); 
  81.  
  82. // Edit field of group 
  83. } elseif ( ! empty( $field_id ) && 'edit_field' === $mode ) { 
  84. xprofile_admin_manage_field( $group_id, $field_id ); 
  85.  
  86. // Delete group 
  87. } elseif ( 'delete_group' === $mode ) { 
  88. xprofile_admin_delete_group( $group_id ); 
  89.  
  90. // Edit group 
  91. } elseif ( 'edit_group' === $mode ) { 
  92. xprofile_admin_manage_group( $group_id ); 
  93.  
  94. // Delete field 
  95. } elseif ( ( false !== $field_id ) && ( 'delete_field' === $mode ) ) { 
  96. xprofile_admin_delete_field( $field_id, 'field'); 
  97.  
  98. // Delete option 
  99. } elseif ( ! empty( $option_id ) && 'delete_option' === $mode ) { 
  100. xprofile_admin_delete_field( $option_id, 'option' ); 
  101.  
  102. // Add group 
  103. } elseif ( 'add_group' == $mode ) { 
  104. xprofile_admin_manage_group(); 
  105.  
  106. } else { 
  107. xprofile_admin_screen( $message, $type ); 
  108.  
  109. /** 
  110. * Output the main XProfile management screen. 
  111. * 
  112. * @since 2.3.0 
  113. * 
  114. * @param string $message Feedback message. 
  115. * @param string $type Feedback type. 
  116. * 
  117. * @todo Improve error message output 
  118. */ 
  119. function xprofile_admin_screen( $message = '', $type = 'error' ) { 
  120.  
  121. // Validate type. 
  122. $type = preg_replace( '|[^a-z]|i', '', $type ); 
  123.  
  124. // Get all of the profile groups & fields. 
  125. $groups = bp_xprofile_get_groups( array( 
  126. 'fetch_fields' => true 
  127. ) ); ?> 
  128.  
  129. <div class="wrap"> 
  130.  
  131. <h1> 
  132. <?php _ex( 'Profile Fields', 'Settings page header', 'buddypress'); ?> 
  133. <a id="add_group" class="add-new-h2" href="users.php?page=bp-profile-setup&mode=add_group"><?php _e( 'Add New Field Group', 'buddypress' ); ?></a> 
  134. </h1> 
  135.  
  136. <form action="" id="profile-field-form" method="post"> 
  137.  
  138. <?php 
  139.  
  140. wp_nonce_field( 'bp_reorder_fields', '_wpnonce_reorder_fields' ); 
  141. wp_nonce_field( 'bp_reorder_groups', '_wpnonce_reorder_groups', false ); 
  142.  
  143. if ( ! empty( $message ) ) : 
  144. $type = ( $type == 'error' ) ? 'error' : 'updated'; ?> 
  145.  
  146. <div id="message" class="<?php echo $type; ?> fade"> 
  147. <p><?php echo esc_html( $message ); ?></p> 
  148. </div> 
  149.  
  150. <?php endif; ?> 
  151.  
  152. <div id="tabs" aria-live="polite" aria-atomic="true" aria-relevant="all"> 
  153. <ul id="field-group-tabs"> 
  154.  
  155. <?php if ( !empty( $groups ) ) : foreach ( $groups as $group ) : ?> 
  156.  
  157. <li id="group_<?php echo esc_attr( $group->id ); ?>"> 
  158. <a href="#tabs-<?php echo esc_attr( $group->id ); ?>" class="ui-tab"> 
  159. <?php 
  160. /** This filter is documented in bp-xprofile/bp-xprofile-template.php */ 
  161. echo esc_html( apply_filters( 'bp_get_the_profile_group_name', $group->name ) ); 
  162. ?> 
  163.  
  164. <?php if ( !$group->can_delete ) : ?> 
  165. <?php _e( '(Primary)', 'buddypress'); ?> 
  166. <?php endif; ?> 
  167.  
  168. </a> 
  169. </li> 
  170.  
  171. <?php endforeach; endif; ?> 
  172.  
  173. </ul> 
  174.  
  175. <?php if ( !empty( $groups ) ) : foreach ( $groups as $group ) : ?> 
  176.  
  177. <noscript> 
  178. <h3><?php 
  179. /** This filter is documented in bp-xprofile/bp-xprofile-template.php */ 
  180. echo esc_html( apply_filters( 'bp_get_the_profile_group_name', $group->name ) ); 
  181. ?></h3> 
  182. </noscript> 
  183.  
  184. <div id="tabs-<?php echo esc_attr( $group->id ); ?>" class="tab-wrapper"> 
  185. <div class="tab-toolbar"> 
  186. <div class="tab-toolbar-left"> 
  187. <a class="button-primary" href="users.php?page=bp-profile-setup&group_id=<?php echo esc_attr( $group->id ); ?>&mode=add_field"><?php _e( 'Add New Field', 'buddypress' ); ?></a> 
  188. <a class="button edit" href="users.php?page=bp-profile-setup&mode=edit_group&group_id=<?php echo esc_attr( $group->id ); ?>"><?php _ex( 'Edit Group', 'Edit Profile Fields Group', 'buddypress' ); ?></a> 
  189.  
  190. <?php if ( $group->can_delete ) : ?> 
  191.  
  192. <div class="delete-button"> 
  193. <a class="confirm submitdelete deletion ajax-option-delete" href="users.php?page=bp-profile-setup&mode=delete_group&group_id=<?php echo esc_attr( $group->id ); ?>"><?php _ex( 'Delete Group', 'Delete Profile Fields Group', 'buddypress' ); ?></a> 
  194. </div> 
  195.  
  196. <?php endif; ?> 
  197.  
  198. <?php 
  199.  
  200. /** 
  201. * Fires at end of action buttons in xprofile management admin. 
  202. * 
  203. * @since 2.2.0 
  204. * 
  205. * @param BP_XProfile_Group $group BP_XProfile_Group object 
  206. * for the current group. 
  207. */ 
  208. do_action( 'xprofile_admin_group_action', $group ); ?> 
  209.  
  210. </div> 
  211. </div> 
  212.  
  213. <?php if ( ! empty( $group->description ) ) : ?> 
  214.  
  215. <p><?php 
  216. /** This filter is documented in bp-xprofile/bp-xprofile-template.php */ 
  217. echo esc_html( apply_filters( 'bp_get_the_profile_group_description', $group->description ) ); 
  218. ?></p> 
  219.  
  220. <?php endif; ?> 
  221.  
  222. <fieldset id="<?php echo esc_attr( $group->id ); ?>" class="connectedSortable field-group" aria-live="polite" aria-atomic="true" aria-relevant="all"> 
  223. <legend class="screen-reader-text"><?php 
  224. /** This filter is documented in bp-xprofile/bp-xprofile-template.php */ 
  225. /** translators: accessibility text */ 
  226. printf( esc_html__( 'Fields for "%s" Group', 'buddypress' ), apply_filters( 'bp_get_the_profile_group_name', $group->name ) ); 
  227. ?></legend> 
  228.  
  229. <?php 
  230.  
  231. if ( !empty( $group->fields ) ) : 
  232. foreach ( $group->fields as $field ) { 
  233.  
  234. // Load the field. 
  235. $field = xprofile_get_field( $field->id ); 
  236.  
  237. $class = ''; 
  238. if ( empty( $field->can_delete ) ) { 
  239. $class = ' core nodrag'; 
  240.  
  241. /** 
  242. * This function handles the WYSIWYG profile field 
  243. * display for the xprofile admin setup screen. 
  244. */ 
  245. xprofile_admin_field( $field, $group, $class ); 
  246.  
  247. } // end for 
  248.  
  249. else : // !$group->fields ?> 
  250.  
  251. <p class="nodrag nofields"><?php _e( 'There are no fields in this group.', 'buddypress' ); ?></p> 
  252.  
  253. <?php endif; // End $group->fields. ?> 
  254.  
  255. </fieldset> 
  256.  
  257. <?php if ( empty( $group->can_delete ) ) : ?> 
  258.  
  259. <p><?php esc_html_e( '* Fields in this group appear on the signup page.', 'buddypress' ); ?></p> 
  260.  
  261. <?php endif; ?> 
  262.  
  263. </div> 
  264.  
  265. <?php endforeach; else : ?> 
  266.  
  267. <div id="message" class="error"><p><?php _ex( 'You have no groups.', 'You have no profile fields groups.', 'buddypress' ); ?></p></div> 
  268. <p><a href="users.php?page=bp-profile-setup&mode=add_group"><?php _ex( 'Add New Group', 'Add New Profile Fields Group', 'buddypress' ); ?></a></p> 
  269.  
  270. <?php endif; ?> 
  271.  
  272. </div> 
  273. </form> 
  274. </div> 
  275.  
  276. <?php 
  277.  
  278. /** 
  279. * Handles the adding or editing of groups. 
  280. * 
  281. * @since 1.0.0 
  282. * 
  283. * @param int|null $group_id Group ID to manage. 
  284. */ 
  285. function xprofile_admin_manage_group( $group_id = null ) { 
  286. global $message, $type; 
  287.  
  288. // Get the field group. 
  289. $group = new BP_XProfile_Group( $group_id ); 
  290.  
  291. // Updating. 
  292. if ( isset( $_POST['save_group'] ) ) { 
  293.  
  294. // Check nonce 
  295. check_admin_referer( 'bp_xprofile_admin_group', 'bp_xprofile_admin_group' ); 
  296.  
  297. // Validate $_POSTed data. 
  298. if ( BP_XProfile_Group::admin_validate() ) { 
  299.  
  300. // Set the group name. 
  301. $group->name = $_POST['group_name']; 
  302.  
  303. // Set the group description. 
  304. if ( ! empty( $_POST['group_description'] ) ) { 
  305. $group->description = $_POST['group_description']; 
  306. } else { 
  307. $group->description = ''; 
  308.  
  309. // Attempt to save the field group. 
  310. if ( false === $group->save() ) { 
  311. $message = __( 'There was an error saving the group. Please try again.', 'buddypress' ); 
  312. $type = 'error'; 
  313.  
  314. // Save successful. 
  315. } else { 
  316. $message = __( 'The group was saved successfully.', 'buddypress' ); 
  317. $type = 'success'; 
  318.  
  319. // @todo remove these old options 
  320. if ( 1 == $group_id ) { 
  321. bp_update_option( 'bp-xprofile-base-group-name', $group->name ); 
  322.  
  323. /** 
  324. * Fires at the end of the group adding/saving process, if successful. 
  325. * 
  326. * @since 1.0.0 
  327. * 
  328. * @param BP_XProfile_Group $group Current BP_XProfile_Group object. 
  329. */ 
  330. do_action( 'xprofile_groups_saved_group', $group ); 
  331.  
  332. xprofile_admin_screen( $message, $type ); 
  333.  
  334. } else { 
  335. $group->render_admin_form( $message ); 
  336. } else { 
  337. $group->render_admin_form(); 
  338.  
  339. /** 
  340. * Handles the deletion of profile data groups. 
  341. * 
  342. * @since 1.0.0 
  343. * 
  344. * @param int $group_id ID of the group to delete. 
  345. */ 
  346. function xprofile_admin_delete_group( $group_id ) { 
  347. global $message, $type; 
  348.  
  349. $group = new BP_XProfile_Group( $group_id ); 
  350.  
  351. if ( !$group->delete() ) { 
  352. $message = _x( 'There was an error deleting the group. Please try again.', 'Error when deleting profile fields group', 'buddypress' ); 
  353. $type = 'error'; 
  354. } else { 
  355. $message = _x( 'The group was deleted successfully.', 'Profile fields group was deleted successfully', 'buddypress' ); 
  356. $type = 'success'; 
  357.  
  358. /** 
  359. * Fires at the end of group deletion process, if successful. 
  360. * 
  361. * @since 1.0.0 
  362. * 
  363. * @param BP_XProfile_Group $group Current BP_XProfile_Group object. 
  364. */ 
  365. do_action( 'xprofile_groups_deleted_group', $group ); 
  366.  
  367. xprofile_admin_screen( $message, $type ); 
  368.  
  369. /** 
  370. * Handles the adding or editing of profile field data for a user. 
  371. * 
  372. * @since 1.0.0 
  373. * 
  374. * @param int $group_id ID of the group. 
  375. * @param int|null $field_id ID of the field being managed. 
  376. */ 
  377. function xprofile_admin_manage_field( $group_id, $field_id = null ) { 
  378. global $wpdb, $message, $groups; 
  379.  
  380. $bp = buddypress(); 
  381.  
  382. if ( is_null( $field_id ) ) { 
  383. $field = new BP_XProfile_Field(); 
  384. } else { 
  385. $field = xprofile_get_field( $field_id ); 
  386.  
  387. $field->group_id = $group_id; 
  388.  
  389. if ( isset( $_POST['saveField'] ) ) { 
  390.  
  391. // Check nonce 
  392. check_admin_referer( 'bp_xprofile_admin_field', 'bp_xprofile_admin_field' ); 
  393.  
  394. if ( BP_XProfile_Field::admin_validate() ) { 
  395. $field->is_required = $_POST['required']; 
  396. $field->type = $_POST['fieldtype']; 
  397. $field->name = $_POST['title']; 
  398.  
  399. if ( ! empty( $_POST['description'] ) ) { 
  400. $field->description = $_POST['description']; 
  401. } else { 
  402. $field->description = ''; 
  403.  
  404. if ( ! empty( $_POST["sort_order_{$field->type}"] ) ) { 
  405. $field->order_by = $_POST["sort_order_{$field->type}"]; 
  406.  
  407. $field->field_order = $wpdb->get_var( $wpdb->prepare( "SELECT field_order FROM {$bp->profile->table_name_fields} WHERE id = %d", $field_id ) ); 
  408. if ( ! is_numeric( $field->field_order ) || is_wp_error( $field->field_order ) ) { 
  409. $field->field_order = (int) $wpdb->get_var( $wpdb->prepare( "SELECT max(field_order) FROM {$bp->profile->table_name_fields} WHERE group_id = %d", $group_id ) ); 
  410. $field->field_order++; 
  411.  
  412. // For new profile fields, set the $field_id. For existing profile 
  413. // fields, this will overwrite $field_id with the same value. 
  414. $field_id = $field->save(); 
  415.  
  416. if ( empty( $field_id ) ) { 
  417. $message = __( 'There was an error saving the field. Please try again.', 'buddypress' ); 
  418. $type = 'error'; 
  419. } else { 
  420. $message = __( 'The field was saved successfully.', 'buddypress' ); 
  421. $type = 'success'; 
  422.  
  423. // @todo remove these old options 
  424. if ( 1 == $field_id ) { 
  425. bp_update_option( 'bp-xprofile-fullname-field-name', $field->name ); 
  426.  
  427. // Set member types. 
  428. if ( isset( $_POST['has-member-types'] ) ) { 
  429. $member_types = array(); 
  430. if ( isset( $_POST['member-types'] ) ) { 
  431. $member_types = stripslashes_deep( $_POST['member-types'] ); 
  432.  
  433. $field->set_member_types( $member_types ); 
  434.  
  435. // Validate default visibility. 
  436. if ( ! empty( $_POST['default-visibility'] ) && in_array( $_POST['default-visibility'], wp_list_pluck( bp_xprofile_get_visibility_levels(), 'id' ) ) ) { 
  437. bp_xprofile_update_field_meta( $field_id, 'default_visibility', $_POST['default-visibility'] ); 
  438.  
  439. // Validate custom visibility. 
  440. if ( ! empty( $_POST['allow-custom-visibility'] ) && in_array( $_POST['allow-custom-visibility'], array( 'allowed', 'disabled' ) ) ) { 
  441. bp_xprofile_update_field_meta( $field_id, 'allow_custom_visibility', $_POST['allow-custom-visibility'] ); 
  442.  
  443. // Validate signup. 
  444. if ( ! empty( $_POST['signup-position'] ) ) { 
  445. bp_xprofile_update_field_meta( $field_id, 'signup_position', (int) $_POST['signup-position'] ); 
  446. } else { 
  447. bp_xprofile_delete_meta( $field_id, 'field', 'signup_position' ); 
  448.  
  449. // Save autolink settings. 
  450. if ( isset( $_POST['do_autolink'] ) && 'on' === wp_unslash( $_POST['do_autolink'] ) ) { 
  451. bp_xprofile_update_field_meta( $field_id, 'do_autolink', 'on' ); 
  452. } else { 
  453. bp_xprofile_update_field_meta( $field_id, 'do_autolink', 'off' ); 
  454.  
  455. if ( $field->type_obj->do_settings_section() ) { 
  456. $settings = isset( $_POST['field-settings'] ) ? wp_unslash( $_POST['field-settings'] ) : array(); 
  457. $field->admin_save_settings( $settings ); 
  458.  
  459. /** 
  460. * Fires at the end of the process to save a field for a user, if successful. 
  461. * 
  462. * @since 1.0.0 
  463. * 
  464. * @param BP_XProfile_Field $field Current BP_XProfile_Field object. 
  465. */ 
  466. do_action( 'xprofile_fields_saved_field', $field ); 
  467.  
  468. $groups = bp_xprofile_get_groups(); 
  469.  
  470. xprofile_admin_screen( $message, $type ); 
  471.  
  472. } else { 
  473. $field->render_admin_form( $message ); 
  474. } else { 
  475. $field->render_admin_form(); 
  476.  
  477. /** 
  478. * Handles the deletion of a profile field (or field option). 
  479. * 
  480. * @since 1.0.0 
  481. * 
  482. * @global string $message The feedback message to show. 
  483. * @global string $type The type of feedback message to show. 
  484. * 
  485. * @param int $field_id The field to delete. 
  486. * @param string $field_type The type of field being deleted. 
  487. * @param bool $delete_data Should the field data be deleted too. 
  488. */ 
  489. function xprofile_admin_delete_field( $field_id, $field_type = 'field', $delete_data = false ) { 
  490. global $message, $type; 
  491.  
  492. // Switch type to 'option' if type is not 'field'. 
  493. // @todo trust this param. 
  494. $field_type = ( 'field' == $field_type ) ? __( 'field', 'buddypress' ) : __( 'option', 'buddypress' ); 
  495. $field = xprofile_get_field( $field_id ); 
  496.  
  497. if ( !$field->delete( (bool) $delete_data ) ) { 
  498. $message = sprintf( __( 'There was an error deleting the %s. Please try again.', 'buddypress' ), $field_type ); 
  499. $type = 'error'; 
  500. } else { 
  501. $message = sprintf( __( 'The %s was deleted successfully!', 'buddypress' ), $field_type ); 
  502. $type = 'success'; 
  503.  
  504. /** 
  505. * Fires at the end of the field deletion process, if successful. 
  506. * 
  507. * @since 1.0.0 
  508. * 
  509. * @param BP_XProfile_Field $field Current BP_XProfile_Field object. 
  510. */ 
  511. do_action( 'xprofile_fields_deleted_field', $field ); 
  512.  
  513. xprofile_admin_screen( $message, $type ); 
  514.  
  515. /** 
  516. * Handles the ajax reordering of fields within a group. 
  517. * 
  518. * @since 1.0.0 
  519. */ 
  520. function xprofile_ajax_reorder_fields() { 
  521.  
  522. // Check the nonce. 
  523. check_admin_referer( 'bp_reorder_fields', '_wpnonce_reorder_fields' ); 
  524.  
  525. if ( empty( $_POST['field_order'] ) ) { 
  526. return false; 
  527.  
  528. parse_str( $_POST['field_order'], $order ); 
  529.  
  530. $field_group_id = $_POST['field_group_id']; 
  531.  
  532. foreach ( (array) $order['draggable_field'] as $position => $field_id ) { 
  533. xprofile_update_field_position( (int) $field_id, (int) $position, (int) $field_group_id ); 
  534. add_action( 'wp_ajax_xprofile_reorder_fields', 'xprofile_ajax_reorder_fields' ); 
  535.  
  536. /** 
  537. * Handles the reordering of field groups. 
  538. * 
  539. * @since 1.5.0 
  540. */ 
  541. function xprofile_ajax_reorder_field_groups() { 
  542.  
  543. // Check the nonce. 
  544. check_admin_referer( 'bp_reorder_groups', '_wpnonce_reorder_groups' ); 
  545.  
  546. if ( empty( $_POST['group_order'] ) ) { 
  547. return false; 
  548.  
  549. parse_str( $_POST['group_order'], $order ); 
  550.  
  551. foreach ( (array) $order['group'] as $position => $field_group_id ) { 
  552. xprofile_update_field_group_position( (int) $field_group_id, (int) $position ); 
  553. add_action( 'wp_ajax_xprofile_reorder_groups', 'xprofile_ajax_reorder_field_groups' ); 
  554.  
  555. /** 
  556. * Handles the WYSIWYG display of each profile field on the edit screen. 
  557. * 
  558. * @since 1.5.0 
  559. * 
  560. * @param BP_XProfile_Field $admin_field Admin field. 
  561. * @param object $admin_group Admin group object. 
  562. * @param string $class Classes to append to output. 
  563. */ 
  564. function xprofile_admin_field( $admin_field, $admin_group, $class = '' ) { 
  565. global $field; 
  566.  
  567. $field = $admin_field; 
  568.  
  569. $field_edit_url = add_query_arg( 
  570. array( 
  571. 'page' => 'bp-profile-setup',  
  572. 'group_id' => (int) $field->group_id,  
  573. 'field_id' => (int) $field->id,  
  574. 'mode' => 'edit_field' 
  575. ),  
  576. network_admin_url( 'users.php' ) 
  577. ); 
  578.  
  579. if ( $field->can_delete ) { 
  580. $field_delete_url = add_query_arg( 
  581. array( 
  582. 'page' => 'bp-profile-setup',  
  583. 'field_id' => (int) $field->id,  
  584. 'mode' => 'delete_field' 
  585. ),  
  586. network_admin_url( 'users.php' ) . '#tabs-' . (int) $field->group_id 
  587. ); 
  588. ?> 
  589.  
  590. <fieldset id="draggable_field_<?php echo esc_attr( $field->id ); ?>" class="sortable<?php echo ' ' . $field->type; if ( !empty( $class ) ) echo ' ' . $class; ?>"> 
  591. <legend> 
  592. <span> 
  593. <?php bp_the_profile_field_name(); ?> 
  594.  
  595. <?php if ( empty( $field->can_delete ) ) : ?><?php esc_html_e( '(Primary)', 'buddypress' ); endif; ?> 
  596. <?php bp_the_profile_field_required_label(); ?> 
  597. <?php if ( bp_xprofile_get_meta( $field->id, 'field', 'signup_position' ) ) : ?><?php esc_html_e( '(Sign-up)', 'buddypress' ); endif; ?> 
  598. <?php if ( bp_get_member_types() ) : echo $field->get_member_type_label(); endif; ?> 
  599.  
  600. <?php 
  601.  
  602. /** 
  603. * Fires at end of legend above the name field in base xprofile group. 
  604. * 
  605. * @since 2.2.0 
  606. * 
  607. * @param BP_XProfile_Field $field Current BP_XProfile_Field 
  608. * object being rendered. 
  609. */ 
  610. do_action( 'xprofile_admin_field_name_legend', $field ); ?> 
  611. </span> 
  612. </legend> 
  613. <div class="field-wrapper"> 
  614.  
  615. <?php 
  616. if ( in_array( $field->type, array_keys( bp_xprofile_get_field_types() ) ) ) { 
  617. $field_type = bp_xprofile_create_field_type( $field->type ); 
  618. $field_type->admin_field_html(); 
  619. } else { 
  620.  
  621. /** 
  622. * Fires after the input if the current field is not in default field types. 
  623. * 
  624. * @since 1.5.0 
  625. * 
  626. * @param BP_XProfile_Field $field Current BP_XProfile_Field 
  627. * object being rendered. 
  628. * @param int $value Integer 1. 
  629. */ 
  630. do_action( 'xprofile_admin_field', $field, 1 ); 
  631. ?> 
  632.  
  633. <?php if ( $field->description ) : ?> 
  634.  
  635. <p class="description"><?php echo esc_attr( $field->description ); ?></p> 
  636.  
  637. <?php endif; ?> 
  638.  
  639. <div class="actions"> 
  640. <a class="button edit" href="<?php echo esc_url( $field_edit_url ); ?>"><?php _ex( 'Edit', 'Edit field link', 'buddypress' ); ?></a> 
  641.  
  642. <?php if ( $field->can_delete ) : ?> 
  643.  
  644. <div class="delete-button"> 
  645. <a class="confirm submit-delete deletion" href="<?php echo esc_url( $field_delete_url ); ?>"><?php _ex( 'Delete', 'Delete field link', 'buddypress' ); ?></a> 
  646. </div> 
  647.  
  648. <?php endif; ?> 
  649.  
  650. <?php 
  651.  
  652. /** 
  653. * Fires at end of field management links in xprofile management admin. 
  654. * 
  655. * @since 2.2.0 
  656. * 
  657. * @param BP_XProfile_Group $group BP_XProfile_Group object 
  658. * for the current group. 
  659. */ 
  660. do_action( 'xprofile_admin_field_action', $field ); ?> 
  661.  
  662. </div> 
  663. </div> 
  664. </fieldset> 
  665.  
  666. <?php 
  667.  
  668. /** 
  669. * Print <option> elements containing the xprofile field types. 
  670. * 
  671. * @since 2.0.0 
  672. * 
  673. * @param string $select_field_type The name of the field type that should be selected. 
  674. * Will defaults to "textbox" if NULL is passed. 
  675. */ 
  676. function bp_xprofile_admin_form_field_types( $select_field_type ) { 
  677. $categories = array(); 
  678.  
  679. if ( is_null( $select_field_type ) ) { 
  680. $select_field_type = 'textbox'; 
  681.  
  682. // Sort each field type into its category. 
  683. foreach ( bp_xprofile_get_field_types() as $field_name => $field_class ) { 
  684. $field_type_obj = new $field_class; 
  685. $the_category = $field_type_obj->category; 
  686.  
  687. // Fallback to a catch-all if category not set. 
  688. if ( ! $the_category ) { 
  689. $the_category = _x( 'Other', 'xprofile field type category', 'buddypress' ); 
  690.  
  691. if ( isset( $categories[$the_category] ) ) { 
  692. $categories[$the_category][] = array( $field_name, $field_type_obj ); 
  693. } else { 
  694. $categories[$the_category] = array( array( $field_name, $field_type_obj ) ); 
  695.  
  696. // Sort the categories alphabetically. ksort()'s SORT_NATURAL is only in PHP >= 5.4 :((. 
  697. uksort( $categories, 'strnatcmp' ); 
  698.  
  699. // Loop through each category and output form <options>. 
  700. foreach ( $categories as $category => $fields ) { 
  701. printf( '<optgroup label="%1$s">', esc_attr( $category ) ); // Already i18n'd in each profile type class. 
  702.  
  703. // Sort these fields types alphabetically. 
  704. uasort( $fields, function( $a, $b ) { return strnatcmp( $a[1]->name, $b[1]->name ); } ); 
  705.  
  706. foreach ( $fields as $field_type_obj ) { 
  707. $field_name = $field_type_obj[0]; 
  708. $field_type_obj = $field_type_obj[1]; 
  709.  
  710. printf( '<option value="%1$s" %2$s>%3$s</option>', esc_attr( $field_name ), selected( $select_field_type, $field_name, false ), esc_html( $field_type_obj->name ) ); 
  711.  
  712. printf( '</optgroup>' ); 
  713.  
  714. // Load the xprofile user admin. 
  715. add_action( 'bp_init', array( 'BP_XProfile_User_Admin', 'register_xprofile_user_admin' ), 11 ); 
.