Skip to:
Content

BuddyPress.org

Changeset 10525


Ignore:
Timestamp:
02/05/2016 05:37:16 AM (9 years ago)
Author:
boonebgorges
Message:

Move bp-xprofile classes to their own files.

See #6870.

Location:
trunk/src/bp-xprofile
Files:
3 edited
3 copied

Legend:

Unmodified
Added
Removed
  • trunk/src/bp-xprofile/bp-xprofile-admin.php

    r10434 r10525  
    1010// Exit if accessed directly.
    1111defined( 'ABSPATH' ) || exit;
     12
     13require dirname( __FILE__ ) . '/classes/class-bp-xprofile-user-admin.php';
    1214
    1315/**
     
    671673}
    672674
    673 if ( ! class_exists( 'BP_XProfile_User_Admin' ) ) :
    674 
    675 /**
    676  * Load xProfile Profile admin area.
    677  *
    678  * @since 2.0.0
    679  */
    680 class BP_XProfile_User_Admin {
    681 
    682     /**
    683      * Setup xProfile User Admin.
    684      *
    685      * @since 2.0.0
    686      *
    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.0
    709      */
    710     public function __construct() {
    711         $this->setup_actions();
    712     }
    713 
    714     /**
    715      * Set admin-related actions and filters.
    716      *
    717      * @since 2.0.0
    718      */
    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.0
    734      *
    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_avatars
    742             || ! 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 playing
    750          * nice with Thickbox width/height see https://core.trac.wordpress.org/ticket/17249
    751          * Using media-upload might be interesting in the future for the send to editor stuff
    752          * and we make sure the tb_window is wide enougth
    753          */
    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.0
    765      *
    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 form
    836      * requests.
    837      *
    838      * @since 2.0.0
    839      *
    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/profile
    876              * displays all groups of fields on a single page, so the list of
    877              * field ids is an array gathering for each group of fields a
    878              * distinct comma separated list of ids.
    879              *
    880              * As a result, before using the wp_parse_id_list() function, we
    881              * must ensure that these ids are "merged" into a single comma
    882              * 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 come
    917                 // through empty. Save them as an empty array so that they don't
    918                 // 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.0
    929                      *
    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.0
    945              *
    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.0
    967      *
    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->ID
    981         ), '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                     <?php
    1009 
    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.0
    1023                      */
    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                         <?php
    1031                         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                     <?php
    1059 
    1060                     /**
    1061                      * Fires at end of custom profile field items on your xprofile screen tab.
    1062                      *
    1063                      * @since 1.1.0
    1064                      */
    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.0
    1078      *
    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     <?php
    1085     }
    1086 
    1087     /**
    1088      * Render the Avatar metabox to moderate inappropriate images.
    1089      *
    1090      * @since 2.0.0
    1091      *
    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_name
    1107             ) ); ?>
    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         <?php
    1137     }
    1138 
    1139 }
    1140 endif; // End class_exists check.
    1141 
    1142675// Load the xprofile user admin.
    1143676add_action( 'bp_init', array( 'BP_XProfile_User_Admin', 'register_xprofile_user_admin' ), 11 );
  • trunk/src/bp-xprofile/bp-xprofile-loader.php

    r10434 r10525  
    1414defined( 'ABSPATH' ) || exit;
    1515
    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 }
     16require dirname( __FILE__ ) . '/classes/class-bp-xprofile-component.php';
    43317
    43418/**
  • trunk/src/bp-xprofile/bp-xprofile-template.php

    r10460 r10525  
    1111defined( 'ABSPATH' ) || exit;
    1212
    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 }
     13require dirname( __FILE__ ) . '/classes/class-bp-xprofile-data-template.php';
    34614
    34715/**
  • trunk/src/bp-xprofile/classes/class-bp-xprofile-component.php

    r10515 r10525  
    431431    }
    432432}
    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  
    11<?php
    22/**
    3  * BuddyPress XProfile Template Tags.
     3 * BuddyPress XProfile Template Loop Class.
    44 *
    55 * @package BuddyPress
    6  * @subpackage XProfileTemplate
    7  * @since 1.5.0
     6 * @since 1.0.0
    87 */
    98
     
    344343    }
    345344}
    346 
    347 /**
    348  * Query for XProfile groups and fields.
    349  *
    350  * @since 1.0.0
    351  *
    352  * @global object $profile_template
    353  * @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 differ
    357  *     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 is
    363  *                                                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 bool
    369  */
    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's
    374     // 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.0
    406      *
    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 mixed
    417  */
    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 mixed
    427  */
    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 mixed
    437  */
    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.0
    447  *
    448  * @param array|string $class Extra classes to append to class attribute.
    449  *                            Pass mutiple class names as an array or
    450  *                            space-delimited string.
    451  *
    452  * @return string
    453  */
    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 string
    463      */
    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.0
    502          *
    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.0
    511          *
    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 mixed
    521  */
    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 bool
    531  */
    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|void
    553      */
    554     function bp_get_the_profile_group_id() {
    555         global $group;
    556 
    557         /**
    558          * Filters the XProfile group ID.
    559          *
    560          * @since 1.1.0
    561          *
    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|void
    578      */
    579     function bp_get_the_profile_group_name() {
    580         global $group;
    581 
    582         /**
    583          * Filters the XProfile group name.
    584          *
    585          * @since 1.0.0
    586          *
    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|void
    603      */
    604     function bp_get_the_profile_group_slug() {
    605         global $group;
    606 
    607         /**
    608          * Filters the XProfile group slug.
    609          *
    610          * @since 1.1.0
    611          *
    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|void
    628      */
    629     function bp_get_the_profile_group_description() {
    630         global $group;
    631 
    632         /**
    633          * Filters the XProfile group description.
    634          *
    635          * @since 1.0.0
    636          *
    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|void
    653      */
    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.0
    664          *
    665          * @param string $value URL for the action attribute on the
    666          *                      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 string
    682      */
    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.0
    701  */
    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.0
    709      *
    710      * @return string
    711      */
    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.0
    728          *
    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 mixed
    738  */
    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 mixed
    748  */
    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|void
    764      */
    765     function bp_get_the_profile_field_id() {
    766         global $field;
    767 
    768         /**
    769          * Filters the XProfile field ID.
    770          *
    771          * @since 1.1.0
    772          *
    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|void
    789      */
    790     function bp_get_the_profile_field_name() {
    791         global $field;
    792 
    793         /**
    794          * Filters the XProfile field name.
    795          *
    796          * @since 1.0.0
    797          *
    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|void
    814      */
    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.0
    824          *
    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|void
    843      */
    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 this
    849          * 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.0
    873          *
    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|void
    892      */
    893     function bp_get_the_profile_field_type() {
    894         global $field;
    895 
    896         /**
    897          * Filters the XProfile field type.
    898          *
    899          * @since 1.1.0
    900          *
    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|void
    917      */
    918     function bp_get_the_profile_field_description() {
    919         global $field;
    920 
    921         /**
    922          * Filters the XProfile field description.
    923          *
    924          * @since 1.1.0
    925          *
    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|void
    942      */
    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.0
    950          *
    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 global
    960  * object and rendered at actions that look like 'bp_field_12_errors'. This
    961  * function allows the action name to be easily concatenated and called in the
    962  * following fashion:
    963  *   do_action( bp_get_the_profile_field_errors_action() );
    964  *
    965  * @since 1.8.0
    966  *
    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.0
    979  *
    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.0
    991      *
    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 a
    998      *                                datebox, otherwise 'day, 'month', or 'year'. Default: false.
    999      *     @type int         $user_id ID of the user whose profile values should be
    1000      *                                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|void
    1047      */
    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.0
    1061          *
    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|void
    1078      */
    1079     function bp_get_the_profile_field_visibility_level() {
    1080         global $field;
    1081 
    1082         // On the registration page, values stored in POST should take
    1083         // precedence over default visibility, so that submitted values
    1084         // 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.0
    1095          *
    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|void
    1112      */
    1113     function bp_get_the_profile_field_visibility_level_label() {
    1114         global $field;
    1115 
    1116         // On the registration page, values stored in POST should take
    1117         // precedence over default visibility, so that submitted values
    1118         // 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.0
    1131          *
    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|string
    1142  */
    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|void
    1167      */
    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.0
    1179          *
    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.0
    1189  *
    1190  * @return array $groups
    1191  */
    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.0
    1204      *
    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.0
    1214  *
    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.0
    1224      *
    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.0
    1234  */
    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 field
    1240      * groups. This action is in a strange place for legacy reasons.
    1241      *
    1242      * @since 1.0.0
    1243      */
    1244     do_action( 'xprofile_profile_group_tabs' );
    1245 }
    1246 
    1247 /**
    1248  * Return the XProfile group tabs.
    1249  *
    1250  * @since 2.3.0
    1251  *
    1252  * @return string
    1253  */
    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.0
    1291      *
    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|void
    1306  */
    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|void
    1319      */
    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.0
    1335          *
    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|void
    1359      */
    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.0
    1370              *
    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.0
    1390      *
    1391      * @return mixed|void
    1392      */
    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.0
    1405          *
    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.0
    1422      * @return mixed|void
    1423      */
    1424     function bp_get_avatar_delete_link() {
    1425 
    1426         /**
    1427          * Filters the link used for deleting an avatar.
    1428          *
    1429          * @since 1.1.0
    1430          *
    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 $retval
    1467      */
    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.0
    1520          *
    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.0
    1532  *
    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.0
    1542      *
    1543      * @param array|string $args Args for the select list.
    1544      * @return string $retval
    1545      */
    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.0
    1598          *
    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.0
    1610  */
    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.0
    1619      *
    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  
    11<?php
    22/**
    3  * BuddyPress XProfile Admin.
     3 * BuddyPress XProfile Admin Class.
    44 *
    55 * @package BuddyPress
    6  * @subpackage XProfileAdmin
    7  * @since 1.0.0
     6 * @since 2.0.0
    87 */
    98
    109// Exit if accessed directly.
    1110defined( 'ABSPATH' ) || exit;
    12 
    13 /**
    14  * Creates the administration interface menus and checks to see if the DB
    15  * 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 bool
    21  */
    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 deleting
    35  * 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 screen
    70  *
    71  * @since 2.3.0
    72  *
    73  * @param string $message Feedback message.
    74  * @param string $type    Feedback type.
    75  *
    76  * @todo Improve error message output
    77  */
    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' => true
    86     ) ); ?>
    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&amp;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             <?php
    98 
    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                                 <?php
    119                                 /** 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><?php
    138                         /** 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&amp;group_id=<?php echo esc_attr( $group->id ); ?>&amp;mode=add_field"><?php _e( 'Add New Field', 'buddypress' ); ?></a>
    147                                 <a class="button edit" href="users.php?page=bp-profile-setup&amp;mode=edit_group&amp;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&amp;mode=delete_group&amp;group_id=<?php echo esc_attr( $group->id ); ?>"><?php _e( 'Delete Group', 'buddypress' ); ?></a>
    153                                     </div>
    154 
    155                                 <?php endif; ?>
    156 
    157                                 <?php
    158 
    159                                 /**
    160                                  * Fires at end of action buttons in xprofile management admin.
    161                                  *
    162                                  * @since 2.2.0
    163                                  *
    164                                  * @param BP_XProfile_Group $group BP_XProfile_Group object
    165                                  *                                 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><?php
    175                             /** 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"><?php
    183                             /** 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                             <?php
    188 
    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 field
    202                                      * display for the xprofile admin setup screen.
    203                                      */
    204                                     xprofile_admin_field( $field, $group, $class );
    205 
    206                                 } // end for
    207 
    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&amp;mode=add_group"><?php _e( 'Add New Group', 'buddypress' ); ?></a></p>
    228 
    229                 <?php endif; ?>
    230 
    231             </div>
    232         </form>
    233     </div>
    234 
    235 <?php
    236 }
    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 options
    276                 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.0
    284                  *
    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.0
    322          *
    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 profile
    374             // 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 options
    385                 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.0
    420                  *
    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.0
    444  * @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.0
    470          *
    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.0
    484  */
    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.0
    508  */
    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.0
    530  *
    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                 <?php
    551 
    552                 /**
    553                  * Fires at end of legend above the name field in base xprofile group.
    554                  *
    555                  * @since 2.2.0
    556                  *
    557                  * @param BP_XProfile_Field $field Current BP_XProfile_Field
    558                  *                                 object being rendered.
    559                  */
    560                 do_action( 'xprofile_admin_field_name_legend', $field ); ?>
    561             </span>
    562         </legend>
    563         <div class="field-wrapper">
    564 
    565             <?php
    566             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.0
    575                  *
    576                  * @param BP_XProfile_Field $field Current BP_XProfile_Field
    577                  *                                 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&amp;group_id=<?php echo esc_attr( $admin_group->id ); ?>&amp;field_id=<?php echo esc_attr( $field->id ); ?>&amp;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&amp;field_id=<?php echo esc_attr( $field->id ); ?>&amp;mode=delete_field"><?php _e( 'Delete', 'buddypress' ); ?></a>
    597                     </div>
    598 
    599                 <?php endif; ?>
    600 
    601                 <?php
    602 
    603                 /**
    604                  * Fires at end of field management links in xprofile management admin.
    605                  *
    606                  * @since 2.2.0
    607                  *
    608                  * @param BP_XProfile_Group $group BP_XProfile_Group object
    609                  *                                 for the current group.
    610                  */
    611                 do_action( 'xprofile_admin_field_action', $field ); ?>
    612 
    613             </div>
    614         </div>
    615     </fieldset>
    616 
    617 <?php
    618 }
    619 
    620 /**
    621  * Print <option> elements containing the xprofile field types.
    622  *
    623  * @since 2.0.0
    624  *
    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 }
    67211
    67312if ( ! class_exists( 'BP_XProfile_User_Admin' ) ) :
     
    1139478}
    1140479endif; // 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.