Changeset 10525
- Timestamp:
- 02/05/2016 05:37:16 AM (9 years ago)
- Location:
- trunk/src/bp-xprofile
- Files:
-
- 3 edited
- 3 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/bp-xprofile/bp-xprofile-admin.php
r10434 r10525 10 10 // Exit if accessed directly. 11 11 defined( 'ABSPATH' ) || exit; 12 13 require dirname( __FILE__ ) . '/classes/class-bp-xprofile-user-admin.php'; 12 14 13 15 /** … … 671 673 } 672 674 673 if ( ! class_exists( 'BP_XProfile_User_Admin' ) ) :674 675 /**676 * Load xProfile Profile admin area.677 *678 * @since 2.0.0679 */680 class BP_XProfile_User_Admin {681 682 /**683 * Setup xProfile User Admin.684 *685 * @since 2.0.0686 *687 * @uses buddypress() to get BuddyPress main instance.688 */689 public static function register_xprofile_user_admin() {690 691 // Bail if not in admin.692 if ( ! is_admin() ) {693 return;694 }695 696 $bp = buddypress();697 698 if ( empty( $bp->profile->admin ) ) {699 $bp->profile->admin = new self;700 }701 702 return $bp->profile->admin;703 }704 705 /**706 * Constructor method.707 *708 * @since 2.0.0709 */710 public function __construct() {711 $this->setup_actions();712 }713 714 /**715 * Set admin-related actions and filters.716 *717 * @since 2.0.0718 */719 private function setup_actions() {720 // Enqueue scripts.721 add_action( 'bp_members_admin_enqueue_scripts', array( $this, 'enqueue_scripts' ), 10, 1 );722 723 // Register the metabox in Member's community admin profile.724 add_action( 'bp_members_admin_xprofile_metabox', array( $this, 'register_metaboxes' ), 10, 3 );725 726 // Saves the profile actions for user ( avatar, profile fields ).727 add_action( 'bp_members_admin_update_user', array( $this, 'user_admin_load' ), 10, 4 );728 }729 730 /**731 * Enqueue needed scripts.732 *733 * @since 2.3.0734 *735 * @param int $screen_id Screen ID being displayed.736 */737 public function enqueue_scripts( $screen_id ) {738 if ( ( false === strpos( $screen_id, 'users_page_bp-profile-edit' )739 && false === strpos( $screen_id, 'profile_page_bp-profile-edit' ) )740 || bp_core_get_root_option( 'bp-disable-avatar-uploads' )741 || ! buddypress()->avatar->show_avatars742 || ! bp_attachments_is_wp_version_supported() ) {743 return;744 }745 746 /**747 * Get Thickbox.748 *749 * We cannot simply use add_thickbox() here as WordPress is not playing750 * nice with Thickbox width/height see https://core.trac.wordpress.org/ticket/17249751 * Using media-upload might be interesting in the future for the send to editor stuff752 * and we make sure the tb_window is wide enougth753 */754 wp_enqueue_style ( 'thickbox' );755 wp_enqueue_script( 'media-upload' );756 757 // Get Avatar Uploader.758 bp_attachments_enqueue_scripts( 'BP_Attachment_Avatar' );759 }760 761 /**762 * Register the xProfile metabox on Community Profile admin page.763 *764 * @since 2.0.0765 *766 * @param int $user_id ID of the user being edited.767 * @param string $screen_id Screen ID to load the metabox in.768 * @param object|null $stats_metabox Context and priority for the stats metabox.769 */770 public function register_metaboxes( $user_id = 0, $screen_id = '', $stats_metabox = null ) {771 772 // Set the screen ID if none was passed.773 if ( empty( $screen_id ) ) {774 $screen_id = buddypress()->members->admin->user_page;775 }776 777 // Setup a new metabox class if none was passed.778 if ( empty( $stats_metabox ) ) {779 $stats_metabox = new StdClass();780 }781 782 // Moving the Stats Metabox.783 $stats_metabox->context = 'side';784 $stats_metabox->priority = 'low';785 786 // Each Group of fields will have his own metabox.787 $profile_args = array(788 'fetch_fields' => false,789 'user_id' => $user_id,790 );791 792 if ( ! bp_is_user_spammer( $user_id ) && bp_has_profile( $profile_args ) ) {793 794 // Loop through field groups and add a metabox for each one.795 while ( bp_profile_groups() ) : bp_the_profile_group();796 add_meta_box(797 'bp_xprofile_user_admin_fields_' . sanitize_key( bp_get_the_profile_group_slug() ),798 esc_html( bp_get_the_profile_group_name() ),799 array( $this, 'user_admin_profile_metaboxes' ),800 $screen_id,801 'normal',802 'core',803 array( 'profile_group_id' => absint( bp_get_the_profile_group_id() ) )804 );805 endwhile;806 807 // If member is already a spammer, show a generic metabox.808 } else {809 add_meta_box(810 'bp_xprofile_user_admin_empty_profile',811 _x( 'User marked as a spammer', 'xprofile user-admin edit screen', 'buddypress' ),812 array( $this, 'user_admin_spammer_metabox' ),813 $screen_id,814 'normal',815 'core'816 );817 }818 819 if ( buddypress()->avatar->show_avatars ) {820 // Avatar Metabox.821 add_meta_box(822 'bp_xprofile_user_admin_avatar',823 _x( 'Profile Photo', 'xprofile user-admin edit screen', 'buddypress' ),824 array( $this, 'user_admin_avatar_metabox' ),825 $screen_id,826 'side',827 'low'828 );829 }830 }831 832 /**833 * Save the profile fields in Members community profile page.834 *835 * Loaded before the page is rendered, this function is processing form836 * requests.837 *838 * @since 2.0.0839 *840 * @param string $doaction Action being run.841 * @param int $user_id ID for the user whose profile is being saved.842 * @param array $request Request being made.843 * @param string $redirect_to Where to redirect user to.844 */845 public function user_admin_load( $doaction = '', $user_id = 0, $request = array(), $redirect_to = '' ) {846 847 // Eventually delete avatar.848 if ( 'delete_avatar' === $doaction ) {849 850 check_admin_referer( 'delete_avatar' );851 852 $redirect_to = remove_query_arg( '_wpnonce', $redirect_to );853 854 if ( bp_core_delete_existing_avatar( array( 'item_id' => $user_id ) ) ) {855 $redirect_to = add_query_arg( 'updated', 'avatar', $redirect_to );856 } else {857 $redirect_to = add_query_arg( 'error', 'avatar', $redirect_to );858 }859 860 bp_core_redirect( $redirect_to );861 862 // Update profile fields.863 } elseif ( isset( $_POST['field_ids'] ) ) {864 865 // Check the nonce.866 check_admin_referer( 'edit-bp-profile_' . $user_id );867 868 // Check we have field ID's.869 if ( empty( $_POST['field_ids'] ) ) {870 $redirect_to = add_query_arg( 'error', '1', $redirect_to );871 bp_core_redirect( $redirect_to );872 }873 874 /**875 * Unlike front-end edit-fields screens, the wp-admin/profile876 * displays all groups of fields on a single page, so the list of877 * field ids is an array gathering for each group of fields a878 * distinct comma separated list of ids.879 *880 * As a result, before using the wp_parse_id_list() function, we881 * must ensure that these ids are "merged" into a single comma882 * separated list.883 */884 $merge_ids = join( ',', $_POST['field_ids'] );885 886 // Explode the posted field IDs into an array so we know which fields have been submitted.887 $posted_field_ids = wp_parse_id_list( $merge_ids );888 $is_required = array();889 890 // Loop through the posted fields formatting any datebox values then validate the field.891 foreach ( (array) $posted_field_ids as $field_id ) {892 if ( ! isset( $_POST['field_' . $field_id ] ) ) {893 if ( ! empty( $_POST['field_' . $field_id . '_day'] ) && ! empty( $_POST['field_' . $field_id . '_month'] ) && ! empty( $_POST['field_' . $field_id . '_year'] ) ) {894 895 // Concatenate the values.896 $date_value = $_POST['field_' . $field_id . '_day'] . ' ' . $_POST['field_' . $field_id . '_month'] . ' ' . $_POST['field_' . $field_id . '_year'];897 898 // Turn the concatenated value into a timestamp.899 $_POST['field_' . $field_id] = date( 'Y-m-d H:i:s', strtotime( $date_value ) );900 }901 }902 903 $is_required[ $field_id ] = xprofile_check_is_required_field( $field_id ) && ! bp_current_user_can( 'bp_moderate' );904 if ( $is_required[ $field_id ] && empty( $_POST['field_' . $field_id ] ) ) {905 $redirect_to = add_query_arg( 'error', '2', $redirect_to );906 bp_core_redirect( $redirect_to );907 }908 }909 910 // Set the errors var.911 $errors = false;912 913 // Now we've checked for required fields, let's save the values.914 foreach ( (array) $posted_field_ids as $field_id ) {915 916 // Certain types of fields (checkboxes, multiselects) may come917 // through empty. Save them as an empty array so that they don't918 // get overwritten by the default on the next edit.919 $value = isset( $_POST['field_' . $field_id] ) ? $_POST['field_' . $field_id] : '';920 921 if ( ! xprofile_set_field_data( $field_id, $user_id, $value, $is_required[ $field_id ] ) ) {922 $errors = true;923 } else {924 925 /**926 * Fires after the saving of each profile field, if successful.927 *928 * @since 1.1.0929 *930 * @param int $field_id ID of the field being updated.931 * @param string $value Value that was saved to the field.932 */933 do_action( 'xprofile_profile_field_data_updated', $field_id, $value );934 }935 936 // Save the visibility level.937 $visibility_level = ! empty( $_POST['field_' . $field_id . '_visibility'] ) ? $_POST['field_' . $field_id . '_visibility'] : 'public';938 xprofile_set_field_visibility_level( $field_id, $user_id, $visibility_level );939 }940 941 /**942 * Fires after all of the profile fields have been saved.943 *944 * @since 1.0.0945 *946 * @param int $user_id ID of the user whose data is being saved.947 * @param array $posted_field_ids IDs of the fields that were submitted.948 * @param bool $errors Whether or not errors occurred during saving.949 */950 do_action( 'xprofile_updated_profile', $user_id, $posted_field_ids, $errors );951 952 // Set the feedback messages.953 if ( ! empty( $errors ) ) {954 $redirect_to = add_query_arg( 'error', '3', $redirect_to );955 } else {956 $redirect_to = add_query_arg( 'updated', '1', $redirect_to );957 }958 959 bp_core_redirect( $redirect_to );960 }961 }962 963 /**964 * Render the xprofile metabox for Community Profile screen.965 *966 * @since 2.0.0967 *968 * @param WP_User|null $user The WP_User object for the user being edited.969 * @param array $args Aray of arguments for metaboxes.970 */971 public function user_admin_profile_metaboxes( $user = null, $args = array() ) {972 973 // Bail if no user ID.974 if ( empty( $user->ID ) ) {975 return;976 }977 978 $r = bp_parse_args( $args['args'], array(979 'profile_group_id' => 0,980 'user_id' => $user->ID981 ), 'bp_xprofile_user_admin_profile_loop_args' );982 983 // We really need these args.984 if ( empty( $r['profile_group_id'] ) || empty( $r['user_id'] ) ) {985 return;986 }987 988 // Bail if no profile fields are available.989 if ( ! bp_has_profile( $r ) ) {990 return;991 }992 993 // Loop through profile groups & fields.994 while ( bp_profile_groups() ) : bp_the_profile_group(); ?>995 996 <input type="hidden" name="field_ids[]" id="<?php echo esc_attr( 'field_ids_' . bp_get_the_profile_group_slug() ); ?>" value="<?php echo esc_attr( bp_get_the_profile_group_field_ids() ); ?>" />997 998 <?php if ( bp_get_the_profile_group_description() ) : ?>999 1000 <p class="description"><?php bp_the_profile_group_description(); ?></p>1001 1002 <?php endif; ?>1003 1004 <?php while ( bp_profile_fields() ) : bp_the_profile_field(); ?>1005 1006 <div<?php bp_field_css_class( 'bp-profile-field' ); ?>>1007 1008 <?php1009 1010 $field_type = bp_xprofile_create_field_type( bp_get_the_profile_field_type() );1011 $field_type->edit_field_html( array( 'user_id' => $r['user_id'] ) );1012 1013 if ( bp_get_the_profile_field_description() ) : ?>1014 1015 <p class="description"><?php bp_the_profile_field_description(); ?></p>1016 1017 <?php endif;1018 1019 /**1020 * Fires before display of visibility form elements for profile metaboxes.1021 *1022 * @since 1.7.01023 */1024 do_action( 'bp_custom_profile_edit_fields_pre_visibility' );1025 1026 $can_change_visibility = bp_current_user_can( 'bp_xprofile_change_field_visibility' ); ?>1027 1028 <p class="field-visibility-settings-<?php echo $can_change_visibility ? 'toggle' : 'notoggle'; ?>" id="field-visibility-settings-toggle-<?php bp_the_profile_field_id(); ?>">1029 1030 <?php1031 printf(1032 __( 'This field can be seen by: %s', 'buddypress' ),1033 '<span class="current-visibility-level">' . bp_get_the_profile_field_visibility_level_label() . '</span>'1034 );1035 ?>1036 1037 <?php if ( $can_change_visibility ) : ?>1038 1039 <a href="#" class="button visibility-toggle-link"><?php esc_html_e( 'Change', 'buddypress' ); ?></a>1040 1041 <?php endif; ?>1042 </p>1043 1044 <?php if ( $can_change_visibility ) : ?>1045 1046 <div class="field-visibility-settings" id="field-visibility-settings-<?php bp_the_profile_field_id() ?>">1047 <fieldset>1048 <legend><?php _e( 'Who can see this field?', 'buddypress' ); ?></legend>1049 1050 <?php bp_profile_visibility_radio_buttons(); ?>1051 1052 </fieldset>1053 <a class="button field-visibility-settings-close" href="#"><?php esc_html_e( 'Close', 'buddypress' ); ?></a>1054 </div>1055 1056 <?php endif; ?>1057 1058 <?php1059 1060 /**1061 * Fires at end of custom profile field items on your xprofile screen tab.1062 *1063 * @since 1.1.01064 */1065 do_action( 'bp_custom_profile_edit_fields' ); ?>1066 1067 </div>1068 1069 <?php endwhile; // End bp_profile_fields(). ?>1070 1071 <?php endwhile; // End bp_profile_groups.1072 }1073 1074 /**1075 * Render the fallback metabox in case a user has been marked as a spammer.1076 *1077 * @since 2.0.01078 *1079 * @param WP_User|null $user The WP_User object for the user being edited.1080 */1081 public function user_admin_spammer_metabox( $user = null ) {1082 ?>1083 <p><?php printf( __( '%s has been marked as a spammer. All BuddyPress data associated with the user has been removed', 'buddypress' ), esc_html( bp_core_get_user_displayname( $user->ID ) ) ) ;?></p>1084 <?php1085 }1086 1087 /**1088 * Render the Avatar metabox to moderate inappropriate images.1089 *1090 * @since 2.0.01091 *1092 * @param WP_User|null $user The WP_User object for the user being edited.1093 */1094 public function user_admin_avatar_metabox( $user = null ) {1095 1096 if ( empty( $user->ID ) ) {1097 return;1098 } ?>1099 1100 <div class="avatar">1101 1102 <?php echo bp_core_fetch_avatar( array(1103 'item_id' => $user->ID,1104 'object' => 'user',1105 'type' => 'full',1106 'title' => $user->display_name1107 ) ); ?>1108 1109 <?php if ( bp_get_user_has_avatar( $user->ID ) ) :1110 1111 $query_args = array(1112 'user_id' => $user->ID,1113 'action' => 'delete_avatar'1114 );1115 1116 if ( ! empty( $_REQUEST['wp_http_referer'] ) ) {1117 $query_args['wp_http_referer'] = urlencode( wp_unslash( $_REQUEST['wp_http_referer'] ) );1118 }1119 1120 $community_url = add_query_arg( $query_args, buddypress()->members->admin->edit_profile_url );1121 $delete_link = wp_nonce_url( $community_url, 'delete_avatar' ); ?>1122 1123 <a href="<?php echo esc_url( $delete_link ); ?>" title="<?php esc_attr_e( 'Delete Profile Photo', 'buddypress' ); ?>" class="bp-xprofile-avatar-user-admin"><?php esc_html_e( 'Delete Profile Photo', 'buddypress' ); ?></a>1124 1125 <?php endif;1126 1127 // Load the Avatar UI templates if user avatar uploads are enabled and current WordPress version is supported.1128 if ( ! bp_core_get_root_option( 'bp-disable-avatar-uploads' ) && bp_attachments_is_wp_version_supported() ) : ?>1129 <a href="#TB_inline?width=800px&height=400px&inlineId=bp-xprofile-avatar-editor" title="<?php esc_attr_e( 'Edit Profile Photo', 'buddypress' );?>" class="thickbox bp-xprofile-avatar-user-edit"><?php esc_html_e( 'Edit Profile Photo', 'buddypress' ); ?></a>1130 <div id="bp-xprofile-avatar-editor" style="display:none;">1131 <?php bp_attachments_get_template_part( 'avatars/index' ); ?>1132 </div>1133 <?php endif; ?>1134 1135 </div>1136 <?php1137 }1138 1139 }1140 endif; // End class_exists check.1141 1142 675 // Load the xprofile user admin. 1143 676 add_action( 'bp_init', array( 'BP_XProfile_User_Admin', 'register_xprofile_user_admin' ), 11 ); -
trunk/src/bp-xprofile/bp-xprofile-loader.php
r10434 r10525 14 14 defined( 'ABSPATH' ) || exit; 15 15 16 /** 17 * Creates our XProfile component. 18 */ 19 class BP_XProfile_Component extends BP_Component { 20 21 /** 22 * Profile field types. 23 * 24 * @since 1.5.0 25 * @var array 26 */ 27 public $field_types; 28 29 /** 30 * The acceptable visibility levels for xprofile fields. 31 * 32 * @see bp_xprofile_get_visibility_levels() 33 * @since 1.6.0 34 * @var array 35 */ 36 public $visibility_levels = array(); 37 38 /** 39 * Start the xprofile component creation process. 40 * 41 * @since 1.5.0 42 */ 43 public function __construct() { 44 parent::start( 45 'xprofile', 46 _x( 'Extended Profiles', 'Component page <title>', 'buddypress' ), 47 buddypress()->plugin_dir, 48 array( 49 'adminbar_myaccount_order' => 20 50 ) 51 ); 52 53 $this->setup_hooks(); 54 } 55 56 /** 57 * Include files. 58 * 59 * @param array $includes Array of files to include. 60 */ 61 public function includes( $includes = array() ) { 62 $includes = array( 63 'cssjs', 64 'cache', 65 'actions', 66 'activity', 67 'screens', 68 'caps', 69 'classes', 70 'filters', 71 'settings', 72 'template', 73 'functions', 74 'notifications', 75 ); 76 77 if ( is_admin() ) { 78 $includes[] = 'admin'; 79 } 80 81 parent::includes( $includes ); 82 } 83 84 /** 85 * Setup globals. 86 * 87 * The BP_XPROFILE_SLUG constant is deprecated, and only used here for 88 * backwards compatibility. 89 * 90 * @since 1.5.0 91 * 92 * @param array $args Array of globals to set up. 93 */ 94 public function setup_globals( $args = array() ) { 95 $bp = buddypress(); 96 97 // Define a slug, if necessary. 98 if ( !defined( 'BP_XPROFILE_SLUG' ) ) { 99 define( 'BP_XPROFILE_SLUG', 'profile' ); 100 } 101 102 // Assign the base group and fullname field names to constants 103 // to use in SQL statements. 104 // Defined conditionally to accommodate unit tests. 105 if ( ! defined( 'BP_XPROFILE_BASE_GROUP_NAME' ) ) { 106 define( 'BP_XPROFILE_BASE_GROUP_NAME', stripslashes( bp_core_get_root_option( 'avatar_default' ) ) ); 107 } 108 109 if ( ! defined( 'BP_XPROFILE_FULLNAME_FIELD_NAME' ) ) { 110 define( 'BP_XPROFILE_FULLNAME_FIELD_NAME', stripslashes( bp_core_get_root_option( 'bp-xprofile-fullname-field-name' ) ) ); 111 } 112 113 /** 114 * Filters the supported field type IDs. 115 * 116 * @since 1.1.0 117 * 118 * @param array $value Array of IDs for the supported field types. 119 */ 120 $this->field_types = apply_filters( 'xprofile_field_types', array_keys( bp_xprofile_get_field_types() ) ); 121 122 // 'option' is a special case. It is not a top-level field, so 123 // does not have an associated BP_XProfile_Field_Type class, 124 // but it must be whitelisted. 125 $this->field_types[] = 'option'; 126 127 // Register the visibility levels. See bp_xprofile_get_visibility_levels() to filter. 128 $this->visibility_levels = array( 129 'public' => array( 130 'id' => 'public', 131 'label' => _x( 'Everyone', 'Visibility level setting', 'buddypress' ) 132 ), 133 'adminsonly' => array( 134 'id' => 'adminsonly', 135 'label' => _x( 'Only Me', 'Visibility level setting', 'buddypress' ) 136 ), 137 'loggedin' => array( 138 'id' => 'loggedin', 139 'label' => _x( 'All Members', 'Visibility level setting', 'buddypress' ) 140 ) 141 ); 142 143 if ( bp_is_active( 'friends' ) ) { 144 $this->visibility_levels['friends'] = array( 145 'id' => 'friends', 146 'label' => _x( 'My Friends', 'Visibility level setting', 'buddypress' ) 147 ); 148 } 149 150 // Tables. 151 $global_tables = array( 152 'table_name_data' => $bp->table_prefix . 'bp_xprofile_data', 153 'table_name_groups' => $bp->table_prefix . 'bp_xprofile_groups', 154 'table_name_fields' => $bp->table_prefix . 'bp_xprofile_fields', 155 'table_name_meta' => $bp->table_prefix . 'bp_xprofile_meta', 156 ); 157 158 $meta_tables = array( 159 'xprofile_group' => $bp->table_prefix . 'bp_xprofile_meta', 160 'xprofile_field' => $bp->table_prefix . 'bp_xprofile_meta', 161 'xprofile_data' => $bp->table_prefix . 'bp_xprofile_meta', 162 ); 163 164 $globals = array( 165 'slug' => BP_XPROFILE_SLUG, 166 'has_directory' => false, 167 'notification_callback' => 'xprofile_format_notifications', 168 'global_tables' => $global_tables, 169 'meta_tables' => $meta_tables, 170 ); 171 172 parent::setup_globals( $globals ); 173 } 174 175 /** 176 * Set up navigation. 177 * 178 * @global BuddyPress $bp The one true BuddyPress instance 179 * 180 * @param array $main_nav Array of main nav items to set up. 181 * @param array $sub_nav Array of sub nav items to set up. 182 */ 183 public function setup_nav( $main_nav = array(), $sub_nav = array() ) { 184 185 // Determine user to use. 186 if ( bp_displayed_user_domain() ) { 187 $user_domain = bp_displayed_user_domain(); 188 } elseif ( bp_loggedin_user_domain() ) { 189 $user_domain = bp_loggedin_user_domain(); 190 } else { 191 return; 192 } 193 194 $access = bp_core_can_edit_settings(); 195 $slug = bp_get_profile_slug(); 196 $profile_link = trailingslashit( $user_domain . $slug ); 197 198 // Add 'Profile' to the main navigation. 199 $main_nav = array( 200 'name' => _x( 'Profile', 'Profile header menu', 'buddypress' ), 201 'slug' => $slug, 202 'position' => 20, 203 'screen_function' => 'xprofile_screen_display_profile', 204 'default_subnav_slug' => 'public', 205 'item_css_id' => $this->id 206 ); 207 208 // Add the subnav items to the profile. 209 $sub_nav[] = array( 210 'name' => _x( 'View', 'Profile header sub menu', 'buddypress' ), 211 'slug' => 'public', 212 'parent_url' => $profile_link, 213 'parent_slug' => $slug, 214 'screen_function' => 'xprofile_screen_display_profile', 215 'position' => 10 216 ); 217 218 // Edit Profile. 219 $sub_nav[] = array( 220 'name' => _x( 'Edit','Profile header sub menu', 'buddypress' ), 221 'slug' => 'edit', 222 'parent_url' => $profile_link, 223 'parent_slug' => $slug, 224 'screen_function' => 'xprofile_screen_edit_profile', 225 'position' => 20, 226 'user_has_access' => $access 227 ); 228 229 // Change Avatar. 230 if ( buddypress()->avatar->show_avatars ) { 231 $sub_nav[] = array( 232 'name' => _x( 'Change Profile Photo', 'Profile header sub menu', 'buddypress' ), 233 'slug' => 'change-avatar', 234 'parent_url' => $profile_link, 235 'parent_slug' => $slug, 236 'screen_function' => 'xprofile_screen_change_avatar', 237 'position' => 30, 238 'user_has_access' => $access 239 ); 240 } 241 242 // Change Cover image. 243 if ( bp_displayed_user_use_cover_image_header() ) { 244 $sub_nav[] = array( 245 'name' => _x( 'Change Cover Image', 'Profile header sub menu', 'buddypress' ), 246 'slug' => 'change-cover-image', 247 'parent_url' => $profile_link, 248 'parent_slug' => $slug, 249 'screen_function' => 'xprofile_screen_change_cover_image', 250 'position' => 40, 251 'user_has_access' => $access 252 ); 253 } 254 255 // The Settings > Profile nav item can only be set up after 256 // the Settings component has run its own nav routine. 257 add_action( 'bp_settings_setup_nav', array( $this, 'setup_settings_nav' ) ); 258 259 parent::setup_nav( $main_nav, $sub_nav ); 260 } 261 262 /** 263 * Set up the Settings > Profile nav item. 264 * 265 * Loaded in a separate method because the Settings component may not 266 * be loaded in time for BP_XProfile_Component::setup_nav(). 267 * 268 * @since 2.1.0 269 */ 270 public function setup_settings_nav() { 271 if ( ! bp_is_active( 'settings' ) ) { 272 return; 273 } 274 275 // Determine user to use. 276 if ( bp_displayed_user_domain() ) { 277 $user_domain = bp_displayed_user_domain(); 278 } elseif ( bp_loggedin_user_domain() ) { 279 $user_domain = bp_loggedin_user_domain(); 280 } else { 281 return; 282 } 283 284 // Get the settings slug. 285 $settings_slug = bp_get_settings_slug(); 286 287 bp_core_new_subnav_item( array( 288 'name' => _x( 'Profile Visibility', 'Profile settings sub nav', 'buddypress' ), 289 'slug' => 'profile', 290 'parent_url' => trailingslashit( $user_domain . $settings_slug ), 291 'parent_slug' => $settings_slug, 292 'screen_function' => 'bp_xprofile_screen_settings', 293 'position' => 30, 294 'user_has_access' => bp_core_can_edit_settings() 295 ) ); 296 } 297 298 /** 299 * Set up the Admin Bar. 300 * 301 * @param array $wp_admin_nav Admin Bar items. 302 */ 303 public function setup_admin_bar( $wp_admin_nav = array() ) { 304 305 // Menus for logged in user. 306 if ( is_user_logged_in() ) { 307 308 // Profile link. 309 $profile_link = trailingslashit( bp_loggedin_user_domain() . bp_get_profile_slug() ); 310 311 // Add the "Profile" sub menu. 312 $wp_admin_nav[] = array( 313 'parent' => buddypress()->my_account_menu_id, 314 'id' => 'my-account-' . $this->id, 315 'title' => _x( 'Profile', 'My Account Profile', 'buddypress' ), 316 'href' => $profile_link 317 ); 318 319 // View Profile. 320 $wp_admin_nav[] = array( 321 'parent' => 'my-account-' . $this->id, 322 'id' => 'my-account-' . $this->id . '-public', 323 'title' => _x( 'View', 'My Account Profile sub nav', 'buddypress' ), 324 'href' => $profile_link 325 ); 326 327 // Edit Profile. 328 $wp_admin_nav[] = array( 329 'parent' => 'my-account-' . $this->id, 330 'id' => 'my-account-' . $this->id . '-edit', 331 'title' => _x( 'Edit', 'My Account Profile sub nav', 'buddypress' ), 332 'href' => trailingslashit( $profile_link . 'edit' ) 333 ); 334 335 // Edit Avatar. 336 if ( buddypress()->avatar->show_avatars ) { 337 $wp_admin_nav[] = array( 338 'parent' => 'my-account-' . $this->id, 339 'id' => 'my-account-' . $this->id . '-change-avatar', 340 'title' => _x( 'Change Profile Photo', 'My Account Profile sub nav', 'buddypress' ), 341 'href' => trailingslashit( $profile_link . 'change-avatar' ) 342 ); 343 } 344 345 if ( bp_displayed_user_use_cover_image_header() ) { 346 $wp_admin_nav[] = array( 347 'parent' => 'my-account-' . $this->id, 348 'id' => 'my-account-' . $this->id . '-change-cover-image', 349 'title' => _x( 'Change Cover Image', 'My Account Profile sub nav', 'buddypress' ), 350 'href' => trailingslashit( $profile_link . 'change-cover-image' ) 351 ); 352 } 353 } 354 355 parent::setup_admin_bar( $wp_admin_nav ); 356 } 357 358 /** 359 * Add custom hooks. 360 * 361 * @since 2.0.0 362 */ 363 public function setup_hooks() { 364 add_filter( 'bp_settings_admin_nav', array( $this, 'setup_settings_admin_nav' ), 2 ); 365 } 366 367 /** 368 * Sets up the title for pages and <title>. 369 */ 370 public function setup_title() { 371 372 if ( bp_is_profile_component() ) { 373 $bp = buddypress(); 374 375 if ( bp_is_my_profile() ) { 376 $bp->bp_options_title = _x( 'My Profile', 'Page title', 'buddypress' ); 377 } else { 378 $bp->bp_options_avatar = bp_core_fetch_avatar( array( 379 'item_id' => bp_displayed_user_id(), 380 'type' => 'thumb', 381 'alt' => sprintf( _x( 'Profile picture of %s', 'Avatar alt', 'buddypress' ), bp_get_displayed_user_fullname() ) 382 ) ); 383 $bp->bp_options_title = bp_get_displayed_user_fullname(); 384 } 385 } 386 387 parent::setup_title(); 388 } 389 390 /** 391 * Setup cache groups. 392 * 393 * @since 2.2.0 394 */ 395 public function setup_cache_groups() { 396 397 // Global groups. 398 wp_cache_add_global_groups( array( 399 'bp_xprofile', 400 'bp_xprofile_data', 401 'bp_xprofile_fields', 402 'bp_xprofile_groups', 403 'xprofile_meta' 404 ) ); 405 406 parent::setup_cache_groups(); 407 } 408 409 /** 410 * Adds "Settings > Profile" subnav item under the "Settings" adminbar menu. 411 * 412 * @since 2.0.0 413 * 414 * @param array $wp_admin_nav The settings adminbar nav array. 415 * @return array 416 */ 417 public function setup_settings_admin_nav( $wp_admin_nav ) { 418 419 // Setup the logged in user variables. 420 $settings_link = trailingslashit( bp_loggedin_user_domain() . bp_get_settings_slug() ); 421 422 // Add the "Profile" subnav item. 423 $wp_admin_nav[] = array( 424 'parent' => 'my-account-' . buddypress()->settings->id, 425 'id' => 'my-account-' . buddypress()->settings->id . '-profile', 426 'title' => _x( 'Profile', 'My Account Settings sub nav', 'buddypress' ), 427 'href' => trailingslashit( $settings_link . 'profile' ) 428 ); 429 430 return $wp_admin_nav; 431 } 432 } 16 require dirname( __FILE__ ) . '/classes/class-bp-xprofile-component.php'; 433 17 434 18 /** -
trunk/src/bp-xprofile/bp-xprofile-template.php
r10460 r10525 11 11 defined( 'ABSPATH' ) || exit; 12 12 13 /** 14 * The main profile template loop class. 15 * 16 * This is responsible for loading profile field, group, and data and displaying it. 17 * 18 * @since 1.0.0 19 */ 20 class BP_XProfile_Data_Template { 21 22 /** 23 * The loop iterator. 24 * 25 * @since 1.5.0 26 * @var int 27 */ 28 public $current_group = -1; 29 30 /** 31 * The number of groups returned by the paged query. 32 * 33 * @since 1.5.0 34 * @var int 35 */ 36 public $group_count; 37 38 /** 39 * Array of groups located by the query. 40 * 41 * @since 1.5.0 42 * @var array 43 */ 44 public $groups; 45 46 /** 47 * The group object currently being iterated on. 48 * 49 * @since 1.5.0 50 * @var object 51 */ 52 public $group; 53 54 /** 55 * The current field. 56 * 57 * @since 1.5.0 58 * @var int 59 */ 60 public $current_field = -1; 61 62 /** 63 * The field count. 64 * 65 * @since 1.5.0 66 * @var int 67 */ 68 public $field_count; 69 70 /** 71 * Field has data. 72 * 73 * @since 1.5.0 74 * @var bool 75 */ 76 public $field_has_data; 77 78 /** 79 * The field. 80 * 81 * @since 1.5.0 82 * @var int 83 */ 84 public $field; 85 86 /** 87 * A flag for whether the loop is currently being iterated. 88 * 89 * @since 1.5.0 90 * @var bool 91 */ 92 public $in_the_loop; 93 94 /** 95 * The user ID. 96 * 97 * @since 1.5.0 98 * @var int 99 */ 100 public $user_id; 101 102 /** 103 * Get activity items, as specified by parameters. 104 * 105 * @see BP_XProfile_Group::get() for more details about parameters. 106 * 107 * @since 2.4.0 Introduced `$member_type` argument. 108 * 109 * @param array|string $args { 110 * An array of arguments. All items are optional. 111 * 112 * @type int $user_id Fetch field data for this user ID. 113 * @type string|array $member_type Limit results to those matching member type(s). 114 * @type int $profile_group_id Field group to fetch fields & data for. 115 * @type int|bool $hide_empty_groups Should empty field groups be skipped. 116 * @type int|bool $fetch_fields Fetch fields for field group. 117 * @type int|bool $fetch_field_data Fetch field data for fields in group. 118 * @type array $exclude_groups Exclude these field groups. 119 * @type array $exclude_fields Exclude these fields. 120 * @type int|bool $hide_empty_fields Should empty fields be skipped. 121 * @type int|bool $fetch_visibility_level Fetch visibility levels. 122 * @type int|bool $update_meta_cache Should metadata cache be updated. 123 * } 124 */ 125 public function __construct( $args = '' ) { 126 127 // Backward compatibility with old method of passing arguments. 128 if ( ! is_array( $args ) || func_num_args() > 1 ) { 129 _deprecated_argument( __METHOD__, '2.3.0', sprintf( __( 'Arguments passed to %1$s should be in an associative array. See the inline documentation at %2$s for more details.', 'buddypress' ), __METHOD__, __FILE__ ) ); 130 131 $old_args_keys = array( 132 0 => 'user_id', 133 1 => 'profile_group_id', 134 2 => 'hide_empty_groups', 135 3 => 'fetch_fields', 136 4 => 'fetch_field_data', 137 5 => 'exclude_groups', 138 6 => 'exclude_fields', 139 7 => 'hide_empty_fields', 140 8 => 'fetch_visibility_level', 141 9 => 'update_meta_cache' 142 ); 143 144 $func_args = func_get_args(); 145 $args = bp_core_parse_args_array( $old_args_keys, $func_args ); 146 } 147 148 $r = wp_parse_args( $args, array( 149 'profile_group_id' => false, 150 'user_id' => false, 151 'member_type' => 'any', 152 'hide_empty_groups' => false, 153 'hide_empty_fields' => false, 154 'fetch_fields' => false, 155 'fetch_field_data' => false, 156 'fetch_visibility_level' => false, 157 'exclude_groups' => false, 158 'exclude_fields' => false, 159 'update_meta_cache' => true 160 ) ); 161 162 $this->groups = bp_xprofile_get_groups( $r ); 163 $this->group_count = count( $this->groups ); 164 $this->user_id = $r['user_id']; 165 } 166 167 /** 168 * Whether or not the loop has field groups. 169 * 170 * @return bool 171 */ 172 public function has_groups() { 173 if ( ! empty( $this->group_count ) ) { 174 return true; 175 } 176 177 return false; 178 } 179 180 /** 181 * Increments to the next group of fields. 182 * 183 * @return object 184 */ 185 public function next_group() { 186 $this->current_group++; 187 188 $this->group = $this->groups[ $this->current_group ]; 189 $this->field_count = 0; 190 191 if ( ! empty( $this->group->fields ) ) { 192 193 /** 194 * Filters the group fields for the next_group method. 195 * 196 * @since 1.1.0 197 * 198 * @param array $fields Array of fields for the group. 199 * @param int $id ID of the field group. 200 */ 201 $this->group->fields = apply_filters( 'xprofile_group_fields', $this->group->fields, $this->group->id ); 202 $this->field_count = count( $this->group->fields ); 203 } 204 205 return $this->group; 206 } 207 208 /** 209 * Rewinds to the start of the groups list. 210 */ 211 public function rewind_groups() { 212 $this->current_group = -1; 213 if ( $this->group_count > 0 ) { 214 $this->group = $this->groups[0]; 215 } 216 } 217 218 /** 219 * Kicks off the profile groups. 220 * 221 * @return bool 222 */ 223 public function profile_groups() { 224 if ( $this->current_group + 1 < $this->group_count ) { 225 return true; 226 } elseif ( $this->current_group + 1 == $this->group_count ) { 227 228 /** 229 * Fires right before the rewinding of profile groups. 230 * 231 * @since 1.1.0 232 */ 233 do_action( 'xprofile_template_loop_end' ); 234 235 // Do some cleaning up after the loop. 236 $this->rewind_groups(); 237 } 238 239 $this->in_the_loop = false; 240 return false; 241 } 242 243 /** 244 * Sets up the profile group. 245 */ 246 public function the_profile_group() { 247 global $group; 248 249 $this->in_the_loop = true; 250 $group = $this->next_group(); 251 252 // Loop has just started. 253 if ( 0 === $this->current_group ) { 254 255 /** 256 * Fires if the current group is the first in the loop. 257 * 258 * @since 1.1.0 259 */ 260 do_action( 'xprofile_template_loop_start' ); 261 } 262 } 263 264 /** Fields ****************************************************************/ 265 266 /** 267 * Increments to the next field. 268 * 269 * @return int 270 */ 271 public function next_field() { 272 $this->current_field++; 273 274 $this->field = $this->group->fields[ $this->current_field ]; 275 276 return $this->field; 277 } 278 279 /** 280 * Rewinds to the start of the fields. 281 */ 282 public function rewind_fields() { 283 $this->current_field = -1; 284 if ( $this->field_count > 0 ) { 285 $this->field = $this->group->fields[0]; 286 } 287 } 288 289 /** 290 * Whether or not the loop has fields. 291 * 292 * @return bool 293 */ 294 public function has_fields() { 295 $has_data = false; 296 297 for ( $i = 0, $count = count( $this->group->fields ); $i < $count; ++$i ) { 298 $field = &$this->group->fields[ $i ]; 299 300 if ( ! empty( $field->data ) && ( $field->data->value != null ) ) { 301 $has_data = true; 302 } 303 } 304 305 return $has_data; 306 } 307 308 /** 309 * Kick off the profile fields. 310 * 311 * @return bool 312 */ 313 public function profile_fields() { 314 if ( $this->current_field + 1 < $this->field_count ) { 315 return true; 316 } elseif ( $this->current_field + 1 == $this->field_count ) { 317 // Do some cleaning up after the loop. 318 $this->rewind_fields(); 319 } 320 321 return false; 322 } 323 324 /** 325 * Set up the profile fields. 326 */ 327 public function the_profile_field() { 328 global $field; 329 330 $field = $this->next_field(); 331 332 // Valid field values of 0 or '0' get caught by empty(), so we have an extra check for these. See #BP5731. 333 if ( ! empty( $field->data ) && ( ! empty( $field->data->value ) || ( '0' === $field->data->value ) ) ) { 334 $value = maybe_unserialize( $field->data->value ); 335 } else { 336 $value = false; 337 } 338 339 if ( ! empty( $value ) || ( '0' === $value ) ) { 340 $this->field_has_data = true; 341 } else { 342 $this->field_has_data = false; 343 } 344 } 345 } 13 require dirname( __FILE__ ) . '/classes/class-bp-xprofile-data-template.php'; 346 14 347 15 /** -
trunk/src/bp-xprofile/classes/class-bp-xprofile-component.php
r10515 r10525 431 431 } 432 432 } 433 434 /**435 * Bootstrap the XProfile component.436 */437 function bp_setup_xprofile() {438 $bp = buddypress();439 440 if ( ! isset( $bp->profile->id ) ) {441 $bp->profile = new BP_XProfile_Component();442 }443 }444 add_action( 'bp_setup_components', 'bp_setup_xprofile', 2 ); -
trunk/src/bp-xprofile/classes/class-bp-xprofile-data-template.php
r10515 r10525 1 1 <?php 2 2 /** 3 * BuddyPress XProfile Template Tags.3 * BuddyPress XProfile Template Loop Class. 4 4 * 5 5 * @package BuddyPress 6 * @subpackage XProfileTemplate 7 * @since 1.5.0 6 * @since 1.0.0 8 7 */ 9 8 … … 344 343 } 345 344 } 346 347 /**348 * Query for XProfile groups and fields.349 *350 * @since 1.0.0351 *352 * @global object $profile_template353 * @see BP_XProfile_Group::get() for full description of `$args` array.354 *355 * @param array|string $args {356 * Array of arguments. See BP_XProfile_Group::get() for full description. Those arguments whose defaults differ357 * from that method are described here:358 * @type string|array $member_type Default: 'any'.359 * @type bool $hide_empty_groups Default: true.360 * @type bool $hide_empty_fields Defaults to true on the Dashboard, on a user's Edit Profile page,361 * or during registration. Otherwise false.362 * @type bool $fetch_visibility_level Defaults to true when an admin is viewing a profile, or when a user is363 * viewing her own profile, or during registration. Otherwise false.364 * @type bool $fetch_fields Default: true.365 * @type bool $fetch_field_data Default: true.366 * }367 *368 * @return bool369 */370 function bp_has_profile( $args = '' ) {371 global $profile_template;372 373 // Only show empty fields if we're on the Dashboard, or we're on a user's374 // profile edit page, or this is a registration page.375 $hide_empty_fields_default = ( ! is_network_admin() && ! is_admin() && ! bp_is_user_profile_edit() && ! bp_is_register_page() );376 377 // We only need to fetch visibility levels when viewing your own profile.378 if ( bp_is_my_profile() || bp_current_user_can( 'bp_moderate' ) || bp_is_register_page() ) {379 $fetch_visibility_level_default = true;380 } else {381 $fetch_visibility_level_default = false;382 }383 384 // Parse arguments.385 $r = bp_parse_args( $args, array(386 'user_id' => bp_displayed_user_id(),387 'member_type' => 'any',388 'profile_group_id' => false,389 'hide_empty_groups' => true,390 'hide_empty_fields' => $hide_empty_fields_default,391 'fetch_fields' => true,392 'fetch_field_data' => true,393 'fetch_visibility_level' => $fetch_visibility_level_default,394 'exclude_groups' => false, // Comma-separated list of profile field group IDs to exclude.395 'exclude_fields' => false, // Comma-separated list of profile field IDs to exclude.396 'update_meta_cache' => true,397 ), 'has_profile' );398 399 // Populate the template loop global.400 $profile_template = new BP_XProfile_Data_Template( $r );401 402 /**403 * Filters whether or not a group has a profile to display.404 *405 * @since 1.1.0406 *407 * @param bool $has_groups Whether or not there are group profiles to display.408 * @param string $profile_template Current profile template being used.409 */410 return apply_filters( 'bp_has_profile', $profile_template->has_groups(), $profile_template );411 }412 413 /**414 * Start off the profile groups.415 *416 * @return mixed417 */418 function bp_profile_groups() {419 global $profile_template;420 return $profile_template->profile_groups();421 }422 423 /**424 * Set up the profile groups.425 *426 * @return mixed427 */428 function bp_the_profile_group() {429 global $profile_template;430 return $profile_template->the_profile_group();431 }432 433 /**434 * Whether or not the group has fields to display.435 *436 * @return mixed437 */438 function bp_profile_group_has_fields() {439 global $profile_template;440 return $profile_template->has_fields();441 }442 443 /**444 * Output the class attribute for a field.445 *446 * @since 1.0.0447 *448 * @param array|string $class Extra classes to append to class attribute.449 * Pass mutiple class names as an array or450 * space-delimited string.451 *452 * @return string453 */454 function bp_field_css_class( $class = false ) {455 echo bp_get_field_css_class( $class );456 }457 458 /**459 * Return the class attribute for a field.460 *461 * @param string|bool $class Extra classes to append to class attribute.462 * @return string463 */464 function bp_get_field_css_class( $class = false ) {465 global $profile_template;466 467 $css_classes = array();468 469 if ( ! empty( $class ) ) {470 if ( ! is_array( $class ) ) {471 $class = preg_split( '#\s+#', $class );472 }473 $css_classes = array_map( 'sanitize_html_class', $class );474 }475 476 // Set a class with the field ID.477 $css_classes[] = 'field_' . $profile_template->field->id;478 479 // Set a class with the field name (sanitized).480 $css_classes[] = 'field_' . sanitize_title( $profile_template->field->name );481 482 // Set a class indicating whether the field is required or optional.483 if ( ! empty( $profile_template->field->is_required ) ) {484 $css_classes[] = 'required-field';485 } else {486 $css_classes[] = 'optional-field';487 }488 489 // Add the field visibility level.490 $css_classes[] = 'visibility-' . esc_attr( bp_get_the_profile_field_visibility_level() );491 492 if ( $profile_template->current_field % 2 == 1 ) {493 $css_classes[] = 'alt';494 }495 496 $css_classes[] = 'field_type_' . sanitize_title( $profile_template->field->type );497 498 /**499 * Filters the field classes to be applied to a field.500 *501 * @since 1.1.0502 *503 * @param array $css_classes Array of classes to be applied to field. Passed by reference.504 */505 $css_classes = apply_filters_ref_array( 'bp_field_css_classes', array( &$css_classes ) );506 507 /**508 * Filters the class HTML attribute to be used on a field.509 *510 * @since 1.1.0511 *512 * @param string $value class HTML attribute with imploded classes.513 */514 return apply_filters( 'bp_get_field_css_class', ' class="' . implode( ' ', $css_classes ) . '"' );515 }516 517 /**518 * Whether or not the XProfile field has data to display.519 *520 * @return mixed521 */522 function bp_field_has_data() {523 global $profile_template;524 return $profile_template->field_has_data;525 }526 527 /**528 * Whether or not the XProfile field has public data to display.529 *530 * @return bool531 */532 function bp_field_has_public_data() {533 global $profile_template;534 535 if ( ! empty( $profile_template->field_has_data ) ) {536 return true;537 }538 539 return false;540 }541 542 /**543 * Output the XProfile group ID.544 */545 function bp_the_profile_group_id() {546 echo bp_get_the_profile_group_id();547 }548 549 /**550 * Return the XProfile group ID.551 *552 * @return mixed|void553 */554 function bp_get_the_profile_group_id() {555 global $group;556 557 /**558 * Filters the XProfile group ID.559 *560 * @since 1.1.0561 *562 * @param int $id ID for the profile group.563 */564 return apply_filters( 'bp_get_the_profile_group_id', $group->id );565 }566 567 /**568 * Output the XProfile group name.569 */570 function bp_the_profile_group_name() {571 echo bp_get_the_profile_group_name();572 }573 574 /**575 * Return the XProfile group name.576 *577 * @return mixed|void578 */579 function bp_get_the_profile_group_name() {580 global $group;581 582 /**583 * Filters the XProfile group name.584 *585 * @since 1.0.0586 *587 * @param string $name Name for the profile group.588 */589 return apply_filters( 'bp_get_the_profile_group_name', $group->name );590 }591 592 /**593 * Output the XProfile group slug.594 */595 function bp_the_profile_group_slug() {596 echo bp_get_the_profile_group_slug();597 }598 599 /**600 * Return the XProfile group slug.601 *602 * @return mixed|void603 */604 function bp_get_the_profile_group_slug() {605 global $group;606 607 /**608 * Filters the XProfile group slug.609 *610 * @since 1.1.0611 *612 * @param string $value Slug for the profile group.613 */614 return apply_filters( 'bp_get_the_profile_group_slug', sanitize_title( $group->name ) );615 }616 617 /**618 * Output the XProfile group description.619 */620 function bp_the_profile_group_description() {621 echo bp_get_the_profile_group_description();622 }623 624 /**625 * Return the XProfile group description.626 *627 * @return mixed|void628 */629 function bp_get_the_profile_group_description() {630 global $group;631 632 /**633 * Filters the XProfile group description.634 *635 * @since 1.0.0636 *637 * @param string $description Description for the profile group.638 */639 return apply_filters( 'bp_get_the_profile_group_description', $group->description );640 }641 642 /**643 * Output the XProfile group edit form action.644 */645 function bp_the_profile_group_edit_form_action() {646 echo bp_get_the_profile_group_edit_form_action();647 }648 649 /**650 * Return the XProfile group edit form action.651 *652 * @return mixed|void653 */654 function bp_get_the_profile_group_edit_form_action() {655 global $group;656 657 // Build the form action URL.658 $form_action = trailingslashit( bp_displayed_user_domain() . bp_get_profile_slug() . '/edit/group/' . $group->id );659 660 /**661 * Filters the action for the XProfile group edit form.662 *663 * @since 1.1.0664 *665 * @param string $value URL for the action attribute on the666 * profile group edit form.667 */668 return apply_filters( 'bp_get_the_profile_group_edit_form_action', $form_action );669 }670 671 /**672 * Output the XProfile group field IDs.673 */674 function bp_the_profile_group_field_ids() {675 echo bp_get_the_profile_group_field_ids();676 }677 678 /**679 * Return the XProfile group field IDs.680 *681 * @return string682 */683 function bp_get_the_profile_group_field_ids() {684 global $group;685 686 $field_ids = '';687 688 if ( !empty( $group->fields ) ) {689 foreach ( (array) $group->fields as $field ) {690 $field_ids .= $field->id . ',';691 }692 }693 694 return substr( $field_ids, 0, -1 );695 }696 697 /**698 * Output a comma-separated list of field IDs that are to be submitted on profile edit.699 *700 * @since 2.1.0701 */702 function bp_the_profile_field_ids() {703 echo bp_get_the_profile_field_ids();704 }705 /**706 * Generate a comma-separated list of field IDs that are to be submitted on profile edit.707 *708 * @since 2.1.0709 *710 * @return string711 */712 function bp_get_the_profile_field_ids() {713 global $profile_template;714 715 $field_ids = array();716 foreach ( $profile_template->groups as $group ) {717 if ( ! empty( $group->fields ) ) {718 $field_ids = array_merge( $field_ids, wp_list_pluck( $group->fields, 'id' ) );719 }720 }721 722 $field_ids = implode( ',', wp_parse_id_list( $field_ids ) );723 724 /**725 * Filters the comma-separated list of field IDs.726 *727 * @since 2.1.0728 *729 * @param string $field_ids Comma-separated field IDs.730 */731 return apply_filters( 'bp_get_the_profile_field_ids', $field_ids );732 }733 734 /**735 * Return the XProfile fields.736 *737 * @return mixed738 */739 function bp_profile_fields() {740 global $profile_template;741 return $profile_template->profile_fields();742 }743 744 /**745 * Sets up the XProfile field.746 *747 * @return mixed748 */749 function bp_the_profile_field() {750 global $profile_template;751 return $profile_template->the_profile_field();752 }753 754 /**755 * Output the XProfile field ID.756 */757 function bp_the_profile_field_id() {758 echo bp_get_the_profile_field_id();759 }760 761 /**762 * Return the XProfile field ID.763 * @return mixed|void764 */765 function bp_get_the_profile_field_id() {766 global $field;767 768 /**769 * Filters the XProfile field ID.770 *771 * @since 1.1.0772 *773 * @param int $id ID for the profile field.774 */775 return apply_filters( 'bp_get_the_profile_field_id', $field->id );776 }777 778 /**779 * Outputs the XProfile field name.780 */781 function bp_the_profile_field_name() {782 echo bp_get_the_profile_field_name();783 }784 785 /**786 * Returns the XProfile field name.787 *788 * @return mixed|void789 */790 function bp_get_the_profile_field_name() {791 global $field;792 793 /**794 * Filters the XProfile field name.795 *796 * @since 1.0.0797 *798 * @param string $name Name for the profile field.799 */800 return apply_filters( 'bp_get_the_profile_field_name', $field->name );801 }802 803 /**804 * Outputs the XProfile field value.805 */806 function bp_the_profile_field_value() {807 echo bp_get_the_profile_field_value();808 }809 810 /**811 * Returns the XProfile field value.812 *813 * @return mixed|void814 */815 function bp_get_the_profile_field_value() {816 global $field;817 818 $field->data->value = bp_unserialize_profile_field( $field->data->value );819 820 /**821 * Filters the XProfile field value.822 *823 * @since 1.0.0824 *825 * @param string $value Value for the profile field.826 * @param string $type Type for the profile field.827 * @param int $id ID for the profile field.828 */829 return apply_filters( 'bp_get_the_profile_field_value', $field->data->value, $field->type, $field->id );830 }831 832 /**833 * Outputs the XProfile field edit value.834 */835 function bp_the_profile_field_edit_value() {836 echo bp_get_the_profile_field_edit_value();837 }838 839 /**840 * Returns the XProfile field edit value.841 *842 * @return mixed|void843 */844 function bp_get_the_profile_field_edit_value() {845 global $field;846 847 /**848 * Check to see if the posted value is different, if it is re-display this849 * value as long as it's not empty and a required field.850 */851 if ( ! isset( $field->data ) ) {852 $field->data = new stdClass;853 }854 855 if ( ! isset( $field->data->value ) ) {856 $field->data->value = '';857 }858 859 if ( isset( $_POST['field_' . $field->id] ) && $field->data->value != $_POST['field_' . $field->id] ) {860 if ( ! empty( $_POST['field_' . $field->id] ) ) {861 $field->data->value = $_POST['field_' . $field->id];862 } else {863 $field->data->value = '';864 }865 }866 867 $field_value = isset( $field->data->value ) ? bp_unserialize_profile_field( $field->data->value ) : '';868 869 /**870 * Filters the XProfile field edit value.871 *872 * @since 1.1.0873 *874 * @param string $field_value Current field edit value.875 * @param string $type Type for the profile field.876 * @param int $id ID for the profile field.877 */878 return apply_filters( 'bp_get_the_profile_field_edit_value', $field_value, $field->type, $field->id );879 }880 881 /**882 * Outputs the XProfile field type.883 */884 function bp_the_profile_field_type() {885 echo bp_get_the_profile_field_type();886 }887 888 /**889 * Returns the XProfile field type.890 *891 * @return mixed|void892 */893 function bp_get_the_profile_field_type() {894 global $field;895 896 /**897 * Filters the XProfile field type.898 *899 * @since 1.1.0900 *901 * @param string $type Type for the profile field.902 */903 return apply_filters( 'bp_the_profile_field_type', $field->type );904 }905 906 /**907 * Outputs the XProfile field description.908 */909 function bp_the_profile_field_description() {910 echo bp_get_the_profile_field_description();911 }912 913 /**914 * Returns the XProfile field description.915 *916 * @return mixed|void917 */918 function bp_get_the_profile_field_description() {919 global $field;920 921 /**922 * Filters the XProfile field description.923 *924 * @since 1.1.0925 *926 * @param string $description Description for the profile field.927 */928 return apply_filters( 'bp_get_the_profile_field_description', $field->description );929 }930 931 /**932 * Outputs the XProfile field input name.933 */934 function bp_the_profile_field_input_name() {935 echo bp_get_the_profile_field_input_name();936 }937 938 /**939 * Retursn the XProfile field input name.940 *941 * @return mixed|void942 */943 function bp_get_the_profile_field_input_name() {944 global $field;945 946 /**947 * Filters the profile field input name.948 *949 * @since 1.1.0950 *951 * @param string $value Value used for the name attribute on an input.952 */953 return apply_filters( 'bp_get_the_profile_field_input_name', 'field_' . $field->id );954 }955 956 /**957 * Returns the action name for any signup errors related to this profile field.958 *959 * In the registration templates, signup errors are pulled from the global960 * object and rendered at actions that look like 'bp_field_12_errors'. This961 * function allows the action name to be easily concatenated and called in the962 * following fashion:963 * do_action( bp_get_the_profile_field_errors_action() );964 *965 * @since 1.8.0966 *967 * @return string The _errors action name corresponding to this profile field.968 */969 function bp_get_the_profile_field_errors_action() {970 global $field;971 return 'bp_field_' . $field->id . '_errors';972 }973 974 /**975 * Displays field options HTML for field types of 'selectbox', 'multiselectbox',976 * 'radio', 'checkbox', and 'datebox'.977 *978 * @since 1.1.0979 *980 * @uses bp_get_the_profile_field_options()981 *982 * @param array $args Specify type for datebox. Allowed 'day', 'month', 'year'.983 */984 function bp_the_profile_field_options( $args = array() ) {985 echo bp_get_the_profile_field_options( $args );986 }987 /**988 * Retrieves field options HTML for field types of 'selectbox', 'multiselectbox', 'radio', 'checkbox', and 'datebox'.989 *990 * @since 1.1.0991 *992 * @uses BP_XProfile_Field::get_children()993 * @uses BP_XProfile_ProfileData::get_value_byid()994 *995 * @param array $args {996 * Array of optional arguments.997 * @type string|bool $type Type of datebox. False if it's not a998 * datebox, otherwise 'day, 'month', or 'year'. Default: false.999 * @type int $user_id ID of the user whose profile values should be1000 * used when rendering options. Default: displayed user.1001 * }1002 *1003 * @return string $vaue Field options markup.1004 */1005 function bp_get_the_profile_field_options( $args = array() ) {1006 global $field;1007 1008 $args = bp_parse_args( $args, array(1009 'type' => false,1010 'user_id' => bp_displayed_user_id(),1011 ), 'get_the_profile_field_options' );1012 1013 /**1014 * In some cases, the $field global is not an instantiation of the BP_XProfile_Field class.1015 * However, we have to make sure that all data originally in $field gets merged back in, after reinstantiation.1016 */1017 if ( ! method_exists( $field, 'get_children' ) ) {1018 $field_obj = xprofile_get_field( $field->id );1019 1020 foreach ( $field as $field_prop => $field_prop_value ) {1021 if ( ! isset( $field_obj->{$field_prop} ) ) {1022 $field_obj->{$field_prop} = $field_prop_value;1023 }1024 }1025 1026 $field = $field_obj;1027 }1028 1029 ob_start();1030 $field->type_obj->edit_field_options_html( $args );1031 $html = ob_get_contents();1032 ob_end_clean();1033 1034 return $html;1035 }1036 1037 /**1038 * Render whether or not a profile field is required.1039 */1040 function bp_the_profile_field_is_required() {1041 echo bp_get_the_profile_field_is_required();1042 }1043 1044 /**1045 * Return whether or not a profile field is required.1046 * @return mixed|void1047 */1048 function bp_get_the_profile_field_is_required() {1049 global $field;1050 1051 $retval = false;1052 1053 if ( isset( $field->is_required ) ) {1054 $retval = $field->is_required;1055 }1056 1057 /**1058 * Filters whether or not a profile field is required.1059 *1060 * @since 1.1.01061 *1062 * @param bool $retval Whether or not the field is required.1063 */1064 return apply_filters( 'bp_get_the_profile_field_is_required', (bool) $retval );1065 }1066 1067 /**1068 * Output the visibility level of this field.1069 */1070 function bp_the_profile_field_visibility_level() {1071 echo bp_get_the_profile_field_visibility_level();1072 }1073 1074 /**1075 * Return the visibility level of this field.1076 *1077 * @return mixed|void1078 */1079 function bp_get_the_profile_field_visibility_level() {1080 global $field;1081 1082 // On the registration page, values stored in POST should take1083 // precedence over default visibility, so that submitted values1084 // are not lost on failure.1085 if ( bp_is_register_page() && ! empty( $_POST['field_' . $field->id . '_visibility'] ) ) {1086 $retval = esc_attr( $_POST['field_' . $field->id . '_visibility'] );1087 } else {1088 $retval = ! empty( $field->visibility_level ) ? $field->visibility_level : 'public';1089 }1090 1091 /**1092 * Filters the profile field visibility level.1093 *1094 * @since 1.6.01095 *1096 * @param string $retval Field visibility level.1097 */1098 return apply_filters( 'bp_get_the_profile_field_visibility_level', $retval );1099 }1100 1101 /**1102 * Echo the visibility level label of this field.1103 */1104 function bp_the_profile_field_visibility_level_label() {1105 echo bp_get_the_profile_field_visibility_level_label();1106 }1107 1108 /**1109 * Return the visibility level label of this field.1110 *1111 * @return mixed|void1112 */1113 function bp_get_the_profile_field_visibility_level_label() {1114 global $field;1115 1116 // On the registration page, values stored in POST should take1117 // precedence over default visibility, so that submitted values1118 // are not lost on failure.1119 if ( bp_is_register_page() && ! empty( $_POST['field_' . $field->id . '_visibility'] ) ) {1120 $level = esc_html( $_POST['field_' . $field->id . '_visibility'] );1121 } else {1122 $level = ! empty( $field->visibility_level ) ? $field->visibility_level : 'public';1123 }1124 1125 $fields = bp_xprofile_get_visibility_levels();1126 1127 /**1128 * Filters the profile field visibility level label.1129 *1130 * @since 1.6.01131 *1132 * @param string $retval Field visibility level label.1133 */1134 return apply_filters( 'bp_get_the_profile_field_visibility_level_label', $fields[ $level ]['label'] );1135 }1136 1137 /**1138 * Return unserialized profile field data.1139 *1140 * @param string $value Content to maybe unserialize.1141 * @return mixed|string1142 */1143 function bp_unserialize_profile_field( $value ) {1144 if ( is_serialized($value) ) {1145 $field_value = maybe_unserialize($value);1146 $field_value = implode( ', ', $field_value );1147 return $field_value;1148 }1149 1150 return $value;1151 }1152 1153 /**1154 * Output XProfile field data.1155 *1156 * @param string|array $args Array of arguments for field data.1157 */1158 function bp_profile_field_data( $args = '' ) {1159 echo bp_get_profile_field_data( $args );1160 }1161 1162 /**1163 * Return XProfile field data.1164 *1165 * @param string|array $args Array of arguments for field data.1166 * @return mixed|void1167 */1168 function bp_get_profile_field_data( $args = '' ) {1169 1170 $r = wp_parse_args( $args, array(1171 'field' => false, // Field name or ID.1172 'user_id' => bp_displayed_user_id()1173 ) );1174 1175 /**1176 * Filters the profile field data.1177 *1178 * @since 1.2.01179 *1180 * @param mixed $value Profile data for a specific field for the user.1181 */1182 return apply_filters( 'bp_get_profile_field_data', xprofile_get_field_data( $r['field'], $r['user_id'] ) );1183 }1184 1185 /**1186 * Get all profile field groups.1187 *1188 * @since 2.1.01189 *1190 * @return array $groups1191 */1192 function bp_profile_get_field_groups() {1193 1194 $groups = wp_cache_get( 'all', 'bp_xprofile_groups' );1195 if ( false === $groups ) {1196 $groups = bp_xprofile_get_groups( array( 'fetch_fields' => true ) );1197 wp_cache_set( 'all', $groups, 'bp_xprofile' );1198 }1199 1200 /**1201 * Filters all profile field groups.1202 *1203 * @since 2.1.01204 *1205 * @param array $groups Array of available profile field groups.1206 */1207 return apply_filters( 'bp_profile_get_field_groups', $groups );1208 }1209 1210 /**1211 * Check if there is more than one group of fields for the profile being edited.1212 *1213 * @since 2.1.01214 *1215 * @return bool True if there is more than one profile field group.1216 */1217 function bp_profile_has_multiple_groups() {1218 $has_multiple_groups = count( (array) bp_profile_get_field_groups() ) > 1;1219 1220 /**1221 * Filters if there is more than one group of fields for the profile being edited.1222 *1223 * @since 2.1.01224 *1225 * @param bool $has_multiple_groups Whether or not there are multiple groups.1226 */1227 return (bool) apply_filters( 'bp_profile_has_multiple_groups', $has_multiple_groups );1228 }1229 1230 /**1231 * Output the tabs to switch between profile field groups.1232 *1233 * @since 1.0.01234 */1235 function bp_profile_group_tabs() {1236 echo bp_get_profile_group_tabs();1237 1238 /**1239 * Fires at the end of the tab output for switching between profile field1240 * groups. This action is in a strange place for legacy reasons.1241 *1242 * @since 1.0.01243 */1244 do_action( 'xprofile_profile_group_tabs' );1245 }1246 1247 /**1248 * Return the XProfile group tabs.1249 *1250 * @since 2.3.01251 *1252 * @return string1253 */1254 function bp_get_profile_group_tabs() {1255 1256 // Get field group data.1257 $groups = bp_profile_get_field_groups();1258 $group_name = bp_get_profile_group_name();1259 $tabs = array();1260 1261 // Loop through field groups and put a tab-lst together.1262 for ( $i = 0, $count = count( $groups ); $i < $count; ++$i ) {1263 1264 // Setup the selected class.1265 $selected = '';1266 if ( $group_name === $groups[ $i ]->name ) {1267 $selected = ' class="current"';1268 }1269 1270 // Skip if group has no fields.1271 if ( empty( $groups[ $i ]->fields ) ) {1272 continue;1273 }1274 1275 // Build the profile field group link.1276 $link = trailingslashit( bp_displayed_user_domain() . bp_get_profile_slug() . '/edit/group/' . $groups[ $i ]->id );1277 1278 // Add tab to end of tabs array.1279 $tabs[] = sprintf(1280 '<li %1$s><a href="%2$s">%3$s</a></li>',1281 $selected,1282 esc_url( $link ),1283 esc_html( apply_filters( 'bp_get_the_profile_group_name', $groups[ $i ]->name ) )1284 );1285 }1286 1287 /**1288 * Filters the tabs to display for profile field groups.1289 *1290 * @since 1.5.01291 *1292 * @param array $tabs Array of tabs to display.1293 * @param array $groups Array of profile groups.1294 * @param string $group_name Name of the current group displayed.1295 */1296 $tabs = apply_filters( 'xprofile_filter_profile_group_tabs', $tabs, $groups, $group_name );1297 1298 return join( '', $tabs );1299 }1300 1301 /**1302 * Output the XProfile group name.1303 *1304 * @param bool $deprecated Deprecated boolean parameter.1305 * @return mixed|void1306 */1307 function bp_profile_group_name( $deprecated = true ) {1308 if ( !$deprecated ) {1309 return bp_get_profile_group_name();1310 } else {1311 echo bp_get_profile_group_name();1312 }1313 }1314 1315 /**1316 * Return the XProfile group name.1317 *1318 * @return mixed|void1319 */1320 function bp_get_profile_group_name() {1321 1322 // Check action variable.1323 $group_id = bp_action_variable( 1 );1324 if ( empty( $group_id ) || ! is_numeric( $group_id ) ) {1325 $group_id = 1;1326 }1327 1328 // Check for cached group.1329 $group = new BP_XProfile_Group( $group_id );1330 1331 /**1332 * Filters the profile group name.1333 *1334 * @since 1.0.01335 *1336 * @param string $name Name of the profile group.1337 */1338 return apply_filters( 'bp_get_profile_group_name', $group->name );1339 }1340 1341 /**1342 * Render a formatted string displaying when a profile was last updated.1343 */1344 function bp_profile_last_updated() {1345 1346 $last_updated = bp_get_profile_last_updated();1347 1348 if ( empty( $last_updated ) ) {1349 _e( 'Profile not recently updated.', 'buddypress' );1350 } else {1351 echo $last_updated;1352 }1353 }1354 1355 /**1356 * Return a formatted string displaying when a profile was last updated.1357 *1358 * @return bool|mixed|void1359 */1360 function bp_get_profile_last_updated() {1361 1362 $last_updated = bp_get_user_meta( bp_displayed_user_id(), 'profile_last_updated', true );1363 1364 if ( ! empty( $last_updated ) ) {1365 1366 /**1367 * Filters the formatted string used to display when a profile was last updated.1368 *1369 * @since 1.0.01370 *1371 * @param string $value Formatted last updated indicator string.1372 */1373 return apply_filters( 'bp_get_profile_last_updated', sprintf( __( 'Profile updated %s', 'buddypress' ), bp_core_time_since( strtotime( $last_updated ) ) ) );1374 }1375 1376 return false;1377 }1378 1379 /**1380 * Display the current profile group ID.1381 */1382 function bp_current_profile_group_id() {1383 echo bp_get_current_profile_group_id();1384 }1385 1386 /**1387 * Return the current profile group ID.1388 *1389 * @since 1.1.01390 *1391 * @return mixed|void1392 */1393 function bp_get_current_profile_group_id() {1394 $profile_group_id = bp_action_variable( 1 );1395 if ( empty( $profile_group_id ) ) {1396 $profile_group_id = 1;1397 }1398 1399 /**1400 * Filters the current profile group ID.1401 *1402 * Possible values are admin/profile/edit/[group-id].1403 *1404 * @since 1.1.01405 *1406 * @param string $profile_group_id Current profile group ID.1407 */1408 return apply_filters( 'bp_get_current_profile_group_id', $profile_group_id );1409 }1410 1411 /**1412 * Render an avatar delete link.1413 */1414 function bp_avatar_delete_link() {1415 echo bp_get_avatar_delete_link();1416 }1417 1418 /**1419 * Return an avatar delete link.1420 *1421 * @since 1.1.01422 * @return mixed|void1423 */1424 function bp_get_avatar_delete_link() {1425 1426 /**1427 * Filters the link used for deleting an avatar.1428 *1429 * @since 1.1.01430 *1431 * @param string $value Nonced URL used for deleting an avatar.1432 */1433 return apply_filters( 'bp_get_avatar_delete_link', wp_nonce_url( bp_displayed_user_domain() . bp_get_profile_slug() . '/change-avatar/delete-avatar/', 'bp_delete_avatar_link' ) );1434 }1435 1436 /**1437 * Render an edit profile button.1438 */1439 function bp_edit_profile_button() {1440 bp_button( array(1441 'id' => 'edit_profile',1442 'component' => 'xprofile',1443 'must_be_logged_in' => true,1444 'block_self' => true,1445 'link_href' => trailingslashit( bp_displayed_user_domain() . bp_get_profile_slug() . '/edit' ),1446 'link_class' => 'edit',1447 'link_text' => __( 'Edit Profile', 'buddypress' ),1448 'link_title' => __( 'Edit Profile', 'buddypress' ),1449 ) );1450 }1451 1452 /** Visibility ****************************************************************/1453 1454 /**1455 * Echo the field visibility radio buttons.1456 *1457 * @param array|string $args Args for the radio buttons.1458 */1459 function bp_profile_visibility_radio_buttons( $args = '' ) {1460 echo bp_profile_get_visibility_radio_buttons( $args );1461 }1462 /**1463 * Return the field visibility radio buttons.1464 *1465 * @param array|string $args Args for the radio buttons.1466 * @return string $retval1467 */1468 function bp_profile_get_visibility_radio_buttons( $args = '' ) {1469 1470 // Parse optional arguments.1471 $r = bp_parse_args( $args, array(1472 'field_id' => bp_get_the_profile_field_id(),1473 'before' => '<ul class="radio">',1474 'after' => '</ul>',1475 'before_radio' => '<li class="%s">',1476 'after_radio' => '</li>',1477 'class' => 'bp-xprofile-visibility'1478 ), 'xprofile_visibility_radio_buttons' );1479 1480 // Empty return value, filled in below if a valid field ID is found.1481 $retval = '';1482 1483 // Only do-the-do if there's a valid field ID.1484 if ( ! empty( $r['field_id'] ) ) :1485 1486 // Start the output buffer.1487 ob_start();1488 1489 // Output anything before.1490 echo $r['before']; ?>1491 1492 <?php if ( bp_current_user_can( 'bp_xprofile_change_field_visibility' ) ) : ?>1493 1494 <?php foreach( bp_xprofile_get_visibility_levels() as $level ) : ?>1495 1496 <?php printf( $r['before_radio'], esc_attr( $level['id'] ) ); ?>1497 1498 <label for="<?php echo esc_attr( 'see-field_' . $r['field_id'] . '_' . $level['id'] ); ?>">1499 <input type="radio" id="<?php echo esc_attr( 'see-field_' . $r['field_id'] . '_' . $level['id'] ); ?>" name="<?php echo esc_attr( 'field_' . $r['field_id'] . '_visibility' ); ?>" value="<?php echo esc_attr( $level['id'] ); ?>" <?php checked( $level['id'], bp_get_the_profile_field_visibility_level() ); ?> />1500 <span class="field-visibility-text"><?php echo esc_html( $level['label'] ); ?></span>1501 </label>1502 1503 <?php echo $r['after_radio']; ?>1504 1505 <?php endforeach; ?>1506 1507 <?php endif;1508 1509 // Output anything after.1510 echo $r['after'];1511 1512 // Get the output buffer and empty it.1513 $retval = ob_get_clean();1514 endif;1515 1516 /**1517 * Filters the radio buttons for setting visibility.1518 *1519 * @since 1.6.01520 *1521 * @param string $retval HTML output for the visibility radio buttons.1522 * @param array $r Parsed arguments to be used with display.1523 * @param array $args Original passed in arguments to be used with display.1524 */1525 return apply_filters( 'bp_profile_get_visibility_radio_buttons', $retval, $r, $args );1526 }1527 1528 /**1529 * Output the XProfile field visibility select list for settings.1530 *1531 * @since 2.0.01532 *1533 * @param array|string $args Args for the select list.1534 */1535 function bp_profile_settings_visibility_select( $args = '' ) {1536 echo bp_profile_get_settings_visibility_select( $args );1537 }1538 /**1539 * Return the XProfile field visibility select list for settings.1540 *1541 * @since 2.0.01542 *1543 * @param array|string $args Args for the select list.1544 * @return string $retval1545 */1546 function bp_profile_get_settings_visibility_select( $args = '' ) {1547 1548 // Parse optional arguments.1549 $r = bp_parse_args( $args, array(1550 'field_id' => bp_get_the_profile_field_id(),1551 'before' => '',1552 'after' => '',1553 'class' => 'bp-xprofile-visibility'1554 ), 'xprofile_settings_visibility_select' );1555 1556 // Empty return value, filled in below if a valid field ID is found.1557 $retval = '';1558 1559 // Only do-the-do if there's a valid field ID.1560 if ( ! empty( $r['field_id'] ) ) :1561 1562 // Start the output buffer.1563 ob_start();1564 1565 // Output anything before.1566 echo $r['before']; ?>1567 1568 <?php if ( bp_current_user_can( 'bp_xprofile_change_field_visibility' ) ) : ?>1569 1570 <label for="<?php echo esc_attr( 'field_' . $r['field_id'] ) ; ?>_visibility" class="bp-screen-reader-text"><?php _e( 'Select visibility', 'buddypress' ); ?></label>1571 <select class="<?php echo esc_attr( $r['class'] ); ?>" name="<?php echo esc_attr( 'field_' . $r['field_id'] ) ; ?>_visibility" id="<?php echo esc_attr( 'field_' . $r['field_id'] ) ; ?>_visibility">1572 1573 <?php foreach ( bp_xprofile_get_visibility_levels() as $level ) : ?>1574 1575 <option value="<?php echo esc_attr( $level['id'] ); ?>" <?php selected( $level['id'], bp_get_the_profile_field_visibility_level() ); ?>><?php echo esc_html( $level['label'] ); ?></option>1576 1577 <?php endforeach; ?>1578 1579 </select>1580 1581 <?php else : ?>1582 1583 <span class="field-visibility-settings-notoggle" title="<?php esc_attr_e( "This field's visibility cannot be changed.", 'buddypress' ); ?>"><?php bp_the_profile_field_visibility_level_label(); ?></span>1584 1585 <?php endif;1586 1587 // Output anything after.1588 echo $r['after'];1589 1590 // Get the output buffer and empty it.1591 $retval = ob_get_clean();1592 endif;1593 1594 /**1595 * Filters the dropdown list for setting visibility.1596 *1597 * @since 2.0.01598 *1599 * @param string $retval HTML output for the visibility dropdown list.1600 * @param array $r Parsed arguments to be used with display.1601 * @param array $args Original passed in arguments to be used with display.1602 */1603 return apply_filters( 'bp_profile_settings_visibility_select', $retval, $r, $args );1604 }1605 1606 /**1607 * Output the 'required' markup in extended profile field labels.1608 *1609 * @since 2.4.01610 */1611 function bp_the_profile_field_required_label() {1612 echo bp_get_the_profile_field_required_label();1613 }1614 1615 /**1616 * Return the 'required' markup in extended profile field labels.1617 *1618 * @since 2.4.01619 *1620 * @return string HTML for the required label.1621 */1622 function bp_get_the_profile_field_required_label() {1623 $retval = '';1624 1625 if ( bp_get_the_profile_field_is_required() ) {1626 $translated_string = __( '(required)', 'buddypress' );1627 1628 $retval = ' <span class="bp-required-field-label">';1629 $retval .= apply_filters( 'bp_get_the_profile_field_required_label', $translated_string, bp_get_the_profile_field_id() );1630 $retval .= '</span>';1631 1632 }1633 1634 return $retval;1635 } -
trunk/src/bp-xprofile/classes/class-bp-xprofile-user-admin.php
r10515 r10525 1 1 <?php 2 2 /** 3 * BuddyPress XProfile Admin .3 * BuddyPress XProfile Admin Class. 4 4 * 5 5 * @package BuddyPress 6 * @subpackage XProfileAdmin 7 * @since 1.0.0 6 * @since 2.0.0 8 7 */ 9 8 10 9 // Exit if accessed directly. 11 10 defined( 'ABSPATH' ) || exit; 12 13 /**14 * Creates the administration interface menus and checks to see if the DB15 * tables are set up.16 *17 * @uses bp_current_user_can() returns true if the current user is a site admin, false if not.18 * @uses add_users_page() Adds a submenu tab to a top level tab in the admin area.19 *20 * @return bool21 */22 function xprofile_add_admin_menu() {23 24 // Bail if current user cannot moderate community.25 if ( ! bp_current_user_can( 'bp_moderate' ) ) {26 return false;27 }28 29 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' );30 }31 add_action( bp_core_admin_hook(), 'xprofile_add_admin_menu' );32 33 /**34 * Handles all actions for the admin area for creating, editing and deleting35 * profile groups and fields.36 *37 * @param string $message Message to display.38 * @param string $type Type of action to be displayed.39 */40 function xprofile_admin( $message = '', $type = 'error' ) {41 42 if ( isset( $_GET['mode'] ) && isset( $_GET['group_id'] ) && 'add_field' == $_GET['mode'] ) {43 xprofile_admin_manage_field( $_GET['group_id'] );44 45 } elseif ( isset( $_GET['mode'] ) && isset( $_GET['group_id'] ) && isset( $_GET['field_id'] ) && 'edit_field' == $_GET['mode'] ) {46 xprofile_admin_manage_field( $_GET['group_id'], $_GET['field_id'] );47 48 } elseif ( isset( $_GET['mode'] ) && isset( $_GET['field_id'] ) && 'delete_field' == $_GET['mode'] ) {49 xprofile_admin_delete_field( $_GET['field_id'], 'field');50 51 } elseif ( isset( $_GET['mode'] ) && isset( $_GET['option_id'] ) && 'delete_option' == $_GET['mode'] ) {52 xprofile_admin_delete_field( $_GET['option_id'], 'option' );53 54 } elseif ( isset( $_GET['mode'] ) && 'add_group' == $_GET['mode'] ) {55 xprofile_admin_manage_group();56 57 } elseif ( isset( $_GET['mode'] ) && isset( $_GET['group_id'] ) && 'delete_group' == $_GET['mode'] ) {58 xprofile_admin_delete_group( $_GET['group_id'] );59 60 } elseif ( isset( $_GET['mode'] ) && isset( $_GET['group_id'] ) && 'edit_group' == $_GET['mode'] ) {61 xprofile_admin_manage_group( $_GET['group_id'] );62 63 } else {64 xprofile_admin_screen( $message, $type );65 }66 }67 68 /**69 * Output the main XProfile management screen70 *71 * @since 2.3.072 *73 * @param string $message Feedback message.74 * @param string $type Feedback type.75 *76 * @todo Improve error message output77 */78 function xprofile_admin_screen( $message = '', $type = 'error' ) {79 80 // Validate type.81 $type = preg_replace( '|[^a-z]|i', '', $type );82 83 // Get all of the profile groups & fields.84 $groups = bp_xprofile_get_groups( array(85 'fetch_fields' => true86 ) ); ?>87 88 <div class="wrap">89 90 <h1>91 <?php _ex( 'Profile Fields', 'Settings page header', 'buddypress'); ?>92 <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>93 </h1>94 95 <form action="" id="profile-field-form" method="post">96 97 <?php98 99 wp_nonce_field( 'bp_reorder_fields', '_wpnonce_reorder_fields' );100 wp_nonce_field( 'bp_reorder_groups', '_wpnonce_reorder_groups', false );101 102 if ( !empty( $message ) ) :103 $type = ( $type == 'error' ) ? 'error' : 'updated'; ?>104 105 <div id="message" class="<?php echo $type; ?> fade">106 <p><?php echo esc_html( $message ); ?></p>107 </div>108 109 <?php endif; ?>110 111 <div id="tabs">112 <ul id="field-group-tabs">113 114 <?php if ( !empty( $groups ) ) : foreach ( $groups as $group ) : ?>115 116 <li id="group_<?php echo esc_attr( $group->id ); ?>">117 <a href="#tabs-<?php echo esc_attr( $group->id ); ?>" class="ui-tab">118 <?php119 /** This filter is documented in bp-xprofile/bp-xprofile-template.php */120 echo esc_html( apply_filters( 'bp_get_the_profile_group_name', $group->name ) );121 ?>122 123 <?php if ( !$group->can_delete ) : ?>124 <?php _e( '(Primary)', 'buddypress'); ?>125 <?php endif; ?>126 127 </a>128 </li>129 130 <?php endforeach; endif; ?>131 132 </ul>133 134 <?php if ( !empty( $groups ) ) : foreach ( $groups as $group ) : ?>135 136 <noscript>137 <h3><?php138 /** This filter is documented in bp-xprofile/bp-xprofile-template.php */139 echo esc_html( apply_filters( 'bp_get_the_profile_group_name', $group->name ) );140 ?></h3>141 </noscript>142 143 <div id="tabs-<?php echo esc_attr( $group->id ); ?>" class="tab-wrapper">144 <div class="tab-toolbar">145 <div class="tab-toolbar-left">146 <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>147 <a class="button edit" href="users.php?page=bp-profile-setup&mode=edit_group&group_id=<?php echo esc_attr( $group->id ); ?>"><?php _e( 'Edit Group', 'buddypress' ); ?></a>148 149 <?php if ( $group->can_delete ) : ?>150 151 <div class="delete-button">152 <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 _e( 'Delete Group', 'buddypress' ); ?></a>153 </div>154 155 <?php endif; ?>156 157 <?php158 159 /**160 * Fires at end of action buttons in xprofile management admin.161 *162 * @since 2.2.0163 *164 * @param BP_XProfile_Group $group BP_XProfile_Group object165 * for the current group.166 */167 do_action( 'xprofile_admin_group_action', $group ); ?>168 169 </div>170 </div>171 172 <?php if ( ! empty( $group->description ) ) : ?>173 174 <p><?php175 /** This filter is documented in bp-xprofile/bp-xprofile-template.php */176 echo esc_html( apply_filters( 'bp_get_the_profile_group_description', $group->description ) );177 ?></p>178 179 <?php endif; ?>180 181 <fieldset id="<?php echo esc_attr( $group->id ); ?>" class="connectedSortable field-group">182 <legend class="screen-reader-text"><?php183 /** This filter is documented in bp-xprofile/bp-xprofile-template.php */184 printf( esc_html__( 'Fields for "%s" Group', 'buddypress' ), apply_filters( 'bp_get_the_profile_group_name', $group->name ) );185 ?></legend>186 187 <?php188 189 if ( !empty( $group->fields ) ) :190 foreach ( $group->fields as $field ) {191 192 // Load the field.193 $field = xprofile_get_field( $field->id );194 195 $class = '';196 if ( empty( $field->can_delete ) ) {197 $class = ' core nodrag';198 }199 200 /**201 * This function handles the WYSIWYG profile field202 * display for the xprofile admin setup screen.203 */204 xprofile_admin_field( $field, $group, $class );205 206 } // end for207 208 else : // !$group->fields ?>209 210 <p class="nodrag nofields"><?php _e( 'There are no fields in this group.', 'buddypress' ); ?></p>211 212 <?php endif; // End $group->fields. ?>213 214 </fieldset>215 216 <?php if ( empty( $group->can_delete ) ) : ?>217 218 <p><?php esc_html_e( '* Fields in this group appear on the signup page.', 'buddypress' ); ?></p>219 220 <?php endif; ?>221 222 </div>223 224 <?php endforeach; else : ?>225 226 <div id="message" class="error"><p><?php _e( 'You have no groups.', 'buddypress' ); ?></p></div>227 <p><a href="users.php?page=bp-profile-setup&mode=add_group"><?php _e( 'Add New Group', 'buddypress' ); ?></a></p>228 229 <?php endif; ?>230 231 </div>232 </form>233 </div>234 235 <?php236 }237 238 /**239 * Handles the adding or editing of groups.240 *241 * @param int|null $group_id Group ID to manage.242 */243 function xprofile_admin_manage_group( $group_id = null ) {244 global $message, $type;245 246 // Get the field group.247 $group = new BP_XProfile_Group( $group_id );248 249 // Updating.250 if ( isset( $_POST['save_group'] ) ) {251 252 // Validate $_POSTed data.253 if ( BP_XProfile_Group::admin_validate() ) {254 255 // Set the group name.256 $group->name = $_POST['group_name'];257 258 // Set the group description.259 if ( ! empty( $_POST['group_description'] ) ) {260 $group->description = $_POST['group_description'];261 } else {262 $group->description = '';263 }264 265 // Attempt to save the field group.266 if ( false === $group->save() ) {267 $message = __( 'There was an error saving the group. Please try again.', 'buddypress' );268 $type = 'error';269 270 // Save successful.271 } else {272 $message = __( 'The group was saved successfully.', 'buddypress' );273 $type = 'success';274 275 // @todo remove these old options276 if ( 1 == $group_id ) {277 bp_update_option( 'bp-xprofile-base-group-name', $group->name );278 }279 280 /**281 * Fires at the end of the group adding/saving process, if successful.282 *283 * @since 1.0.0284 *285 * @param BP_XProfile_Group $group Current BP_XProfile_Group object.286 */287 do_action( 'xprofile_groups_saved_group', $group );288 }289 290 unset( $_GET['mode'] );291 xprofile_admin( $message, $type );292 293 } else {294 $group->render_admin_form( $message );295 }296 } else {297 $group->render_admin_form();298 }299 }300 301 /**302 * Handles the deletion of profile data groups.303 *304 * @param int $group_id ID of the group to delete.305 */306 function xprofile_admin_delete_group( $group_id ) {307 global $message, $type;308 309 $group = new BP_XProfile_Group( $group_id );310 311 if ( !$group->delete() ) {312 $message = __( 'There was an error deleting the group. Please try again.', 'buddypress' );313 $type = 'error';314 } else {315 $message = __( 'The group was deleted successfully.', 'buddypress' );316 $type = 'success';317 318 /**319 * Fires at the end of group deletion process, if successful.320 *321 * @since 1.0.0322 *323 * @param BP_XProfile_Group $group Current BP_XProfile_Group object.324 */325 do_action( 'xprofile_groups_deleted_group', $group );326 }327 328 unset( $_GET['mode'] );329 xprofile_admin( $message, $type );330 }331 332 /**333 * Handles the adding or editing of profile field data for a user.334 *335 * @param int $group_id ID of the group.336 * @param int|null $field_id ID of the field being managed.337 */338 function xprofile_admin_manage_field( $group_id, $field_id = null ) {339 global $wpdb, $message, $groups;340 341 $bp = buddypress();342 343 if ( is_null( $field_id ) ) {344 $field = new BP_XProfile_Field();345 } else {346 $field = xprofile_get_field( $field_id );347 }348 349 $field->group_id = $group_id;350 351 if ( isset( $_POST['saveField'] ) ) {352 if ( BP_XProfile_Field::admin_validate() ) {353 $field->is_required = $_POST['required'];354 $field->type = $_POST['fieldtype'];355 $field->name = $_POST['title'];356 357 if ( ! empty( $_POST['description'] ) ) {358 $field->description = $_POST['description'];359 } else {360 $field->description = '';361 }362 363 if ( ! empty( $_POST["sort_order_{$field->type}"] ) ) {364 $field->order_by = $_POST["sort_order_{$field->type}"];365 }366 367 $field->field_order = $wpdb->get_var( $wpdb->prepare( "SELECT field_order FROM {$bp->profile->table_name_fields} WHERE id = %d", $field_id ) );368 if ( empty( $field->field_order ) || is_wp_error( $field->field_order ) ) {369 $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 ) );370 $field->field_order++;371 }372 373 // For new profile fields, set the $field_id. For existing profile374 // fields, this will overwrite $field_id with the same value.375 $field_id = $field->save();376 377 if ( empty( $field_id ) ) {378 $message = __( 'There was an error saving the field. Please try again.', 'buddypress' );379 $type = 'error';380 } else {381 $message = __( 'The field was saved successfully.', 'buddypress' );382 $type = 'success';383 384 // @todo remove these old options385 if ( 1 == $field_id ) {386 bp_update_option( 'bp-xprofile-fullname-field-name', $field->name );387 }388 389 // Set member types.390 if ( isset( $_POST['has-member-types'] ) ) {391 $member_types = array();392 if ( isset( $_POST['member-types'] ) ) {393 $member_types = stripslashes_deep( $_POST['member-types'] );394 }395 396 $field->set_member_types( $member_types );397 }398 399 // Validate default visibility.400 if ( ! empty( $_POST['default-visibility'] ) && in_array( $_POST['default-visibility'], wp_list_pluck( bp_xprofile_get_visibility_levels(), 'id' ) ) ) {401 bp_xprofile_update_field_meta( $field_id, 'default_visibility', $_POST['default-visibility'] );402 }403 404 // Validate custom visibility.405 if ( ! empty( $_POST['allow-custom-visibility'] ) && in_array( $_POST['allow-custom-visibility'], array( 'allowed', 'disabled' ) ) ) {406 bp_xprofile_update_field_meta( $field_id, 'allow_custom_visibility', $_POST['allow-custom-visibility'] );407 }408 409 // Validate signup.410 if ( ! empty( $_POST['signup-position'] ) ) {411 bp_xprofile_update_field_meta( $field_id, 'signup_position', (int) $_POST['signup-position'] );412 } else {413 bp_xprofile_delete_meta( $field_id, 'field', 'signup_position' );414 }415 416 /**417 * Fires at the end of the process to save a field for a user, if successful.418 *419 * @since 1.0.0420 *421 * @param BP_XProfile_Field $field Current BP_XProfile_Field object.422 */423 do_action( 'xprofile_fields_saved_field', $field );424 425 $groups = bp_xprofile_get_groups();426 }427 428 unset( $_GET['mode'] );429 430 xprofile_admin( $message, $type );431 432 } else {433 $field->render_admin_form( $message );434 }435 } else {436 $field->render_admin_form();437 }438 }439 440 /**441 * Handles the deletion of a profile field (or field option).442 *443 * @since 1.0.0444 * @global string $message The feedback message to show.445 * @global $type The type of feedback message to show.446 *447 * @param int $field_id The field to delete.448 * @param string $field_type The type of field being deleted.449 * @param bool $delete_data Should the field data be deleted too.450 */451 function xprofile_admin_delete_field( $field_id, $field_type = 'field', $delete_data = false ) {452 global $message, $type;453 454 // Switch type to 'option' if type is not 'field'.455 // @todo trust this param.456 $field_type = ( 'field' == $field_type ) ? __( 'field', 'buddypress' ) : __( 'option', 'buddypress' );457 $field = xprofile_get_field( $field_id );458 459 if ( !$field->delete( (bool) $delete_data ) ) {460 $message = sprintf( __( 'There was an error deleting the %s. Please try again.', 'buddypress' ), $field_type );461 $type = 'error';462 } else {463 $message = sprintf( __( 'The %s was deleted successfully!', 'buddypress' ), $field_type );464 $type = 'success';465 466 /**467 * Fires at the end of the field deletion process, if successful.468 *469 * @since 1.0.0470 *471 * @param BP_XProfile_Field $field Current BP_XProfile_Field object.472 */473 do_action( 'xprofile_fields_deleted_field', $field );474 }475 476 unset( $_GET['mode'] );477 xprofile_admin( $message, $type );478 }479 480 /**481 * Handles the ajax reordering of fields within a group.482 *483 * @since 1.0.0484 */485 function xprofile_ajax_reorder_fields() {486 487 // Check the nonce.488 check_admin_referer( 'bp_reorder_fields', '_wpnonce_reorder_fields' );489 490 if ( empty( $_POST['field_order'] ) ) {491 return false;492 }493 494 parse_str( $_POST['field_order'], $order );495 496 $field_group_id = $_POST['field_group_id'];497 498 foreach ( (array) $order['draggable_field'] as $position => $field_id ) {499 xprofile_update_field_position( (int) $field_id, (int) $position, (int) $field_group_id );500 }501 }502 add_action( 'wp_ajax_xprofile_reorder_fields', 'xprofile_ajax_reorder_fields' );503 504 /**505 * Handles the reordering of field groups.506 *507 * @since 1.5.0508 */509 function xprofile_ajax_reorder_field_groups() {510 511 // Check the nonce.512 check_admin_referer( 'bp_reorder_groups', '_wpnonce_reorder_groups' );513 514 if ( empty( $_POST['group_order'] ) ) {515 return false;516 }517 518 parse_str( $_POST['group_order'], $order );519 520 foreach ( (array) $order['group'] as $position => $field_group_id ) {521 xprofile_update_field_group_position( (int) $field_group_id, (int) $position );522 }523 }524 add_action( 'wp_ajax_xprofile_reorder_groups', 'xprofile_ajax_reorder_field_groups' );525 526 /**527 * Handles the WYSIWYG display of each profile field on the edit screen.528 *529 * @since 1.5.0530 *531 * @param object $admin_field Admin field.532 * @param object $admin_group Admin group object.533 * @param string $class Classes to append to output.534 */535 function xprofile_admin_field( $admin_field, $admin_group, $class = '' ) {536 global $field;537 538 $field = $admin_field; ?>539 540 <fieldset id="draggable_field_<?php echo esc_attr( $field->id ); ?>"class="sortable<?php echo ' ' . $field->type; if ( !empty( $class ) ) echo ' ' . $class; ?>">541 <legend>542 <span>543 <?php bp_the_profile_field_name(); ?>544 545 <?php if ( empty( $field->can_delete ) ) : ?><?php esc_html_e( '(Primary)', 'buddypress' ); endif; ?>546 <?php bp_the_profile_field_required_label(); ?>547 <?php if ( bp_xprofile_get_meta( $field->id, 'field', 'signup_position' ) ) : ?><?php esc_html_e( '(Sign-up)', 'buddypress' ); endif; ?>548 <?php if ( bp_get_member_types() ) : echo $field->get_member_type_label(); endif; ?>549 550 <?php551 552 /**553 * Fires at end of legend above the name field in base xprofile group.554 *555 * @since 2.2.0556 *557 * @param BP_XProfile_Field $field Current BP_XProfile_Field558 * object being rendered.559 */560 do_action( 'xprofile_admin_field_name_legend', $field ); ?>561 </span>562 </legend>563 <div class="field-wrapper">564 565 <?php566 if ( in_array( $field->type, array_keys( bp_xprofile_get_field_types() ) ) ) {567 $field_type = bp_xprofile_create_field_type( $field->type );568 $field_type->admin_field_html();569 } else {570 571 /**572 * Fires after the input if the current field is not in default field types.573 *574 * @since 1.5.0575 *576 * @param BP_XProfile_Field $field Current BP_XProfile_Field577 * object being rendered.578 * @param int $value Integer 1.579 */580 do_action( 'xprofile_admin_field', $field, 1 );581 }582 ?>583 584 <?php if ( $field->description ) : ?>585 586 <p class="description"><?php echo esc_attr( $field->description ); ?></p>587 588 <?php endif; ?>589 590 <div class="actions">591 <a class="button edit" href="users.php?page=bp-profile-setup&group_id=<?php echo esc_attr( $admin_group->id ); ?>&field_id=<?php echo esc_attr( $field->id ); ?>&mode=edit_field"><?php _e( 'Edit', 'buddypress' ); ?></a>592 593 <?php if ( $field->can_delete ) : ?>594 595 <div class="delete-button">596 <a class="confirm submit-delete deletion" href="users.php?page=bp-profile-setup&field_id=<?php echo esc_attr( $field->id ); ?>&mode=delete_field"><?php _e( 'Delete', 'buddypress' ); ?></a>597 </div>598 599 <?php endif; ?>600 601 <?php602 603 /**604 * Fires at end of field management links in xprofile management admin.605 *606 * @since 2.2.0607 *608 * @param BP_XProfile_Group $group BP_XProfile_Group object609 * for the current group.610 */611 do_action( 'xprofile_admin_field_action', $field ); ?>612 613 </div>614 </div>615 </fieldset>616 617 <?php618 }619 620 /**621 * Print <option> elements containing the xprofile field types.622 *623 * @since 2.0.0624 *625 * @param string $select_field_type The name of the field type that should be selected.626 * Will defaults to "textbox" if NULL is passed.627 */628 function bp_xprofile_admin_form_field_types( $select_field_type ) {629 $categories = array();630 631 if ( is_null( $select_field_type ) ) {632 $select_field_type = 'textbox';633 }634 635 // Sort each field type into its category.636 foreach ( bp_xprofile_get_field_types() as $field_name => $field_class ) {637 $field_type_obj = new $field_class;638 $the_category = $field_type_obj->category;639 640 // Fallback to a catch-all if category not set.641 if ( ! $the_category ) {642 $the_category = _x( 'Other', 'xprofile field type category', 'buddypress' );643 }644 645 if ( isset( $categories[$the_category] ) ) {646 $categories[$the_category][] = array( $field_name, $field_type_obj );647 } else {648 $categories[$the_category] = array( array( $field_name, $field_type_obj ) );649 }650 }651 652 // Sort the categories alphabetically. ksort()'s SORT_NATURAL is only in PHP >= 5.4 :((.653 uksort( $categories, 'strnatcmp' );654 655 // Loop through each category and output form <options>.656 foreach ( $categories as $category => $fields ) {657 printf( '<optgroup label="%1$s">', esc_attr( $category ) ); // Already i18n'd in each profile type class.658 659 // Sort these fields types alphabetically.660 uasort( $fields, create_function( '$a, $b', 'return strnatcmp( $a[1]->name, $b[1]->name );' ) );661 662 foreach ( $fields as $field_type_obj ) {663 $field_name = $field_type_obj[0];664 $field_type_obj = $field_type_obj[1];665 666 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 ) );667 }668 669 printf( '</optgroup>' );670 }671 }672 11 673 12 if ( ! class_exists( 'BP_XProfile_User_Admin' ) ) : … … 1139 478 } 1140 479 endif; // End class_exists check. 1141 1142 // Load the xprofile user admin.1143 add_action( 'bp_init', array( 'BP_XProfile_User_Admin', 'register_xprofile_user_admin' ), 11 );
Note: See TracChangeset
for help on using the changeset viewer.