[ Index ] |
PHP Cross Reference of BuddyPress |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * BuddyPress XProfile Admin. 4 * 5 * @package BuddyPress 6 * @subpackage XProfileAdmin 7 * @since 1.0.0 8 */ 9 10 // Exit if accessed directly. 11 defined( 'ABSPATH' ) || exit; 12 13 /** 14 * Creates the administration interface menus and checks to see if the DB 15 * tables are set up. 16 * 17 * @since 1.0.0 18 * 19 * @return bool 20 */ 21 function xprofile_add_admin_menu() { 22 23 // Bail if current user cannot moderate community. 24 if ( ! bp_current_user_can( 'bp_moderate' ) ) { 25 return false; 26 } 27 28 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' ); 29 } 30 add_action( bp_core_admin_hook(), 'xprofile_add_admin_menu' ); 31 32 /** 33 * Handles all actions for the admin area for creating, editing and deleting 34 * profile groups and fields. 35 * 36 * @since 1.0.0 37 * 38 * @param string $message Message to display. 39 * @param string $type Type of action to be displayed. 40 */ 41 function xprofile_admin( $message = '', $type = 'error' ) { 42 43 // What mode? 44 $mode = ! empty( $_GET['mode'] ) 45 ? sanitize_key( $_GET['mode'] ) 46 : false; 47 48 // Group ID. 49 $group_id = ! empty( $_GET['group_id'] ) 50 ? intval( $_GET['group_id'] ) 51 : false; 52 53 // Field ID. 54 $field_id = ! empty( $_GET['field_id'] ) 55 ? intval( $_GET['field_id'] ) 56 : false; 57 58 // Option ID. 59 $option_id = ! empty( $_GET['option_id'] ) 60 ? intval( $_GET['option_id'] ) 61 : false; 62 63 // Allowed modes. 64 $allowed_modes = array( 65 'add_group', 66 'edit_group', 67 'delete_group', 68 'do_delete_group', 69 'add_field', 70 'edit_field', 71 'delete_field', 72 'do_delete_field', 73 'delete_option', 74 'do_delete_option' 75 ); 76 77 // Is an allowed mode. 78 if ( in_array( $mode, $allowed_modes, true ) ) { 79 80 // All group actions. 81 if ( false !== $group_id ) { 82 83 // Add field to group. 84 if ( 'add_field' == $mode ) { 85 xprofile_admin_manage_field( $group_id ); 86 87 // Edit field of group. 88 } elseif ( ! empty( $field_id ) && 'edit_field' === $mode ) { 89 xprofile_admin_manage_field( $group_id, $field_id ); 90 91 // Delete group. 92 } elseif ( in_array( $mode, array( 'delete_group', 'do_delete_group' ), true ) ) { 93 xprofile_admin_delete_group( $group_id ); 94 95 // Edit group. 96 } elseif ( 'edit_group' === $mode ) { 97 xprofile_admin_manage_group( $group_id ); 98 } 99 100 // Delete field. 101 } elseif ( ( false !== $field_id ) && ( in_array( $mode, array( 'delete_field', 'do_delete_field' ), true ) ) ) { 102 xprofile_admin_delete_field( $field_id, 'field' ); 103 104 // Delete option. 105 } elseif ( ! empty( $option_id ) && in_array( $mode, array( 'delete_option', 'do_delete_option' ), true ) ) { 106 xprofile_admin_delete_field( $option_id, 'option' ); 107 108 // Add group. 109 } elseif ( 'add_group' == $mode ) { 110 xprofile_admin_manage_group(); 111 } 112 113 } else { 114 xprofile_admin_screen( $message, $type ); 115 } 116 } 117 118 /** 119 * Output the main XProfile management screen. 120 * 121 * @since 2.3.0 122 * 123 * @param string $message Feedback message. 124 * @param string $type Feedback type. 125 * 126 * @todo Improve error message output 127 */ 128 function xprofile_admin_screen( $message = '', $type = 'error' ) { 129 130 // Users admin URL. 131 $url = bp_get_admin_url( 'users.php' ); 132 133 // Add Group. 134 $add_group_url = add_query_arg( array( 135 'page' => 'bp-profile-setup', 136 'mode' => 'add_group' 137 ), $url ); 138 139 // Validate type. 140 $type = preg_replace( '|[^a-z]|i', '', $type ); 141 142 // Get all of the profile groups & fields. 143 $groups = bp_xprofile_get_groups( array( 144 'fetch_fields' => true 145 ) ); ?> 146 147 <div class="wrap"> 148 <h1 class="wp-heading-inline"><?php _ex( 'Profile Fields', 'Settings page header', 'buddypress'); ?></h1> 149 150 <a id="add_group" class="page-title-action" href="<?php echo esc_url( $add_group_url ); ?>"><?php _e( 'Add New Field Group', 'buddypress' ); ?></a> 151 152 <hr class="wp-header-end"> 153 154 <form action="" id="profile-field-form" method="post"> 155 156 <?php 157 158 wp_nonce_field( 'bp_reorder_fields', '_wpnonce_reorder_fields' ); 159 wp_nonce_field( 'bp_reorder_groups', '_wpnonce_reorder_groups', false ); 160 161 if ( ! empty( $message ) ) : 162 $type = ( $type == 'error' ) ? 'error' : 'updated'; ?> 163 164 <div id="message" class="<?php echo $type; ?> fade notice is-dismissible"> 165 <p><?php echo esc_html( $message ); ?></p> 166 </div> 167 168 <?php endif; ?> 169 170 <div id="tabs" aria-live="polite" aria-atomic="true" aria-relevant="all"> 171 <ul id="field-group-tabs"> 172 173 <?php if ( !empty( $groups ) ) : foreach ( $groups as $group ) : ?> 174 175 <li id="group_<?php echo esc_attr( $group->id ); ?>"> 176 <a href="#tabs-<?php echo esc_attr( $group->id ); ?>" class="ui-tab"> 177 <?php 178 /** This filter is documented in bp-xprofile/bp-xprofile-template.php */ 179 echo esc_html( apply_filters( 'bp_get_the_profile_group_name', $group->name ) ); 180 ?> 181 182 <?php if ( !$group->can_delete ) : ?> 183 <?php _e( '(Primary)', 'buddypress'); ?> 184 <?php endif; ?> 185 186 </a> 187 </li> 188 189 <?php endforeach; endif; ?> 190 191 <li id="signup-group" class="not-sortable last"> 192 <a href="#tabs-signup-group" class="ui-tab"> 193 <?php esc_html_e( 'Signup Fields', 'buddypress' ); ?> 194 </a> 195 </li> 196 197 </ul> 198 199 <?php if ( !empty( $groups ) ) : foreach ( $groups as $group ) : 200 201 // Add Field to Group URL. 202 $add_field_url = add_query_arg( array( 203 'page' => 'bp-profile-setup', 204 'mode' => 'add_field', 205 'group_id' => (int) $group->id 206 ), $url ); 207 208 // Edit Group URL. 209 $edit_group_url = add_query_arg( array( 210 'page' => 'bp-profile-setup', 211 'mode' => 'edit_group', 212 'group_id' => (int) $group->id 213 ), $url ); 214 215 // Delete Group URL. 216 $delete_group_url = wp_nonce_url( add_query_arg( array( 217 'page' => 'bp-profile-setup', 218 'mode' => 'delete_group', 219 'group_id' => (int) $group->id 220 ), $url ), 'bp_xprofile_delete_group' ); ?> 221 222 <noscript> 223 <h3><?php 224 /** This filter is documented in bp-xprofile/bp-xprofile-template.php */ 225 echo esc_html( apply_filters( 'bp_get_the_profile_group_name', $group->name ) ); 226 ?></h3> 227 </noscript> 228 229 <div id="tabs-<?php echo esc_attr( $group->id ); ?>" class="tab-wrapper"> 230 <div class="tab-toolbar"> 231 <div class="tab-toolbar-left"> 232 <a class="button-primary" href="<?php echo esc_url( $add_field_url ); ?>"><?php _e( 'Add New Field', 'buddypress' ); ?></a> 233 <a class="button edit" href="<?php echo esc_url( $edit_group_url ); ?>"><?php _ex( 'Edit Group', 'Edit Profile Fields Group', 'buddypress' ); ?></a> 234 235 <?php if ( $group->can_delete ) : ?> 236 237 <div class="delete-button"> 238 <a class="confirm submitdelete deletion ajax-option-delete" href="<?php echo esc_url( $delete_group_url ); ?>"><?php _ex( 'Delete Group', 'Delete Profile Fields Group', 'buddypress' ); ?></a> 239 </div> 240 241 <?php endif; ?> 242 243 <?php 244 245 /** 246 * Fires at end of action buttons in xprofile management admin. 247 * 248 * @since 2.2.0 249 * 250 * @param BP_XProfile_Group $group BP_XProfile_Group object 251 * for the current group. 252 */ 253 do_action( 'xprofile_admin_group_action', $group ); ?> 254 255 </div> 256 </div> 257 258 <?php if ( ! empty( $group->description ) ) : ?> 259 260 <p><?php 261 /** This filter is documented in bp-xprofile/bp-xprofile-template.php */ 262 echo esc_html( apply_filters( 'bp_get_the_profile_group_description', $group->description ) ); 263 ?></p> 264 265 <?php endif; ?> 266 267 <fieldset id="<?php echo esc_attr( $group->id ); ?>" class="connectedSortable field-group" aria-live="polite" aria-atomic="true" aria-relevant="all"> 268 <legend class="screen-reader-text"><?php 269 /** This filter is documented in bp-xprofile/bp-xprofile-template.php */ 270 /* translators: accessibility text */ 271 printf( esc_html__( 'Fields for "%s" Group', 'buddypress' ), apply_filters( 'bp_get_the_profile_group_name', $group->name ) ); 272 ?></legend> 273 274 <?php 275 276 if ( !empty( $group->fields ) ) : 277 foreach ( $group->fields as $field ) { 278 279 // Load the field. 280 $field = xprofile_get_field( $field->id, null, false ); 281 282 $class = ''; 283 if ( empty( $field->can_delete ) ) { 284 $class = ' core nodrag'; 285 } 286 287 /** 288 * This function handles the WYSIWYG profile field 289 * display for the xprofile admin setup screen. 290 */ 291 xprofile_admin_field( $field, $group, $class ); 292 293 } // end for 294 295 else : // !$group->fields ?> 296 297 <p class="nodrag nofields"><?php _e( 'There are no fields in this group.', 'buddypress' ); ?></p> 298 299 <?php endif; // End $group->fields. ?> 300 301 </fieldset> 302 303 </div> 304 305 <?php endforeach; else : ?> 306 307 <div id="message" class="error notice is-dismissible"><p><?php _ex( 'You have no groups.', 'You have no profile fields groups.', 'buddypress' ); ?></p></div> 308 <p><a href="<?php echo esc_url( $add_group_url ); ?>"><?php _ex( 'Add New Group', 'Add New Profile Fields Group', 'buddypress' ); ?></a></p> 309 310 <?php endif; ?> 311 312 <?php 313 $signup_groups = bp_xprofile_get_groups( 314 array( 315 'fetch_fields' => true, 316 'signup_fields_only' => true, 317 ) 318 ); 319 $has_signup_fields = false; 320 $signup_fields = array(); 321 $signup_fields_order = bp_xprofile_get_signup_field_ids(); 322 ?> 323 <div id="tabs-signup-group" class="tab-wrapper"> 324 <div class="tab-toolbar"> 325 <p class="description"><?php esc_html_e( 'Drag fields from other groups and drop them on the above tab to include them into your registration form.', 'buddypress' ); ?></p> 326 </div> 327 <fieldset id="signup-fields" class="connectedSortable field-group" aria-live="polite" aria-atomic="true" aria-relevant="all"> 328 <legend class="screen-reader-text"> 329 <?php esc_html_e( 'Fields to use into the registration form', 'buddypress' );?> 330 </legend> 331 332 <?php 333 if ( ! empty( $signup_groups ) ) { 334 foreach ( $signup_groups as $signup_group ) { 335 if ( ! empty( $signup_group->fields ) ) { 336 $has_signup_fields = true; 337 338 foreach ( $signup_group->fields as $signup_field ) { 339 // Load the field. 340 $_signup_field = xprofile_get_field( $signup_field, null, false ); 341 342 /** 343 * This function handles the WYSIWYG profile field 344 * display for the xprofile admin setup screen. 345 */ 346 $signup_fields[ $_signup_field->id ] = bp_xprofile_admin_get_signup_field( $_signup_field, $signup_group, '' ); 347 } 348 } 349 } 350 351 // Output signup fields according to their signup position. 352 foreach ( $signup_fields_order as $ordered_signup_field_id ) { 353 if ( ! isset( $signup_fields[ $ordered_signup_field_id ] ) ) { 354 continue; 355 } 356 357 echo $signup_fields[ $ordered_signup_field_id ]; 358 } 359 } 360 361 if ( ! $has_signup_fields ) { 362 ?> 363 <p class="nodrag nofields"><?php esc_html_e( 'There are no registration fields set. The registration form uses the primary group by default.', 'buddypress' ); ?></p> 364 <?php 365 } 366 ?> 367 </fieldset> 368 369 <?php if ( bp_get_signup_allowed() ) : ?> 370 <p><?php esc_html_e( '* Fields in this group appear on the registration page.', 'buddypress' ); ?></p> 371 <?php else : ?> 372 <p> 373 <?php 374 // Include a link to edit settings. 375 $settings_link = ''; 376 377 if ( is_multisite() && current_user_can( 'manage_network_users') ) { 378 $settings_link = sprintf( 379 ' <a href="%1$s">%2$s</a>.', 380 esc_url( network_admin_url( 'settings.php' ) ), 381 esc_html__( 'Edit settings', 'buddypress' ) 382 ); 383 } elseif ( current_user_can( 'manage_options' ) ) { 384 $settings_link = sprintf( 385 ' <a href="%1$s">%2$s</a>.', 386 esc_url( bp_get_admin_url( 'options-general.php' ) ), 387 esc_html__( 'Edit settings', 'buddypress' ) 388 ); 389 } 390 391 printf( 392 /* translators: %s is the link to the registration settings. */ 393 esc_html__( '* Fields in this group will appear on the registration page as soon as users will be able to register to your site.%s', 'buddypress' ), 394 $settings_link 395 ); 396 ?> 397 </p> 398 <?php endif; ?> 399 </div> 400 </div> 401 </form> 402 </div> 403 <?php 404 } 405 406 /** 407 * Handles the adding or editing of groups. 408 * 409 * @since 1.0.0 410 * 411 * @param int|null $group_id Group ID to manage. 412 */ 413 function xprofile_admin_manage_group( $group_id = null ) { 414 global $message, $type; 415 416 // Get the field group. 417 $group = new BP_XProfile_Group( $group_id ); 418 419 // Updating. 420 if ( isset( $_POST['save_group'] ) ) { 421 422 // Check nonce. 423 check_admin_referer( 'bp_xprofile_admin_group', 'bp_xprofile_admin_group' ); 424 425 // Validate $_POSTed data. 426 if ( BP_XProfile_Group::admin_validate() ) { 427 428 // Set the group name. 429 $group->name = $_POST['group_name']; 430 431 // Set the group description. 432 if ( ! empty( $_POST['group_description'] ) ) { 433 $group->description = $_POST['group_description']; 434 } else { 435 $group->description = ''; 436 } 437 438 // Attempt to save the field group. 439 if ( false === $group->save() ) { 440 $message = __( 'There was an error saving the group. Please try again.', 'buddypress' ); 441 $type = 'error'; 442 443 // Save successful. 444 } else { 445 $message = __( 'The group was saved successfully.', 'buddypress' ); 446 $type = 'success'; 447 448 // @todo remove these old options. 449 if ( 1 == $group_id ) { 450 bp_update_option( 'bp-xprofile-base-group-name', $group->name ); 451 } 452 453 /** 454 * Fires at the end of the group adding/saving process, if successful. 455 * 456 * @since 1.0.0 457 * 458 * @param BP_XProfile_Group $group Current BP_XProfile_Group object. 459 */ 460 do_action( 'xprofile_groups_saved_group', $group ); 461 } 462 463 xprofile_admin_screen( $message, $type ); 464 465 } else { 466 $group->render_admin_form( $message ); 467 } 468 } else { 469 $group->render_admin_form(); 470 } 471 } 472 473 /** 474 * Handles the deletion of profile data groups. 475 * 476 * @since 1.0.0 477 * 478 * @param int $group_id ID of the group to delete. 479 */ 480 function xprofile_admin_delete_group( $group_id ) { 481 global $message, $type; 482 483 check_admin_referer( 'bp_xprofile_delete_group' ); 484 485 $mode = ! empty( $_GET['mode'] ) 486 ? sanitize_key( $_GET['mode'] ) 487 : false; 488 489 // Display the group delete confirmation screen. 490 if ( 'delete_group' === $mode ) { 491 xprofile_admin_delete_group_screen( $group_id ); 492 493 // Handle the deletion of group. 494 } else { 495 $group = new BP_XProfile_Group( $group_id ); 496 497 if ( ! $group->delete() ) { 498 $message = _x( 'There was an error deleting the group. Please try again.', 'Error when deleting profile fields group', 'buddypress' ); 499 $type = 'error'; 500 } else { 501 $message = _x( 'The group was deleted successfully.', 'Profile fields group was deleted successfully', 'buddypress' ); 502 $type = 'success'; 503 504 /** 505 * Fires at the end of group deletion process, if successful. 506 * 507 * @since 1.0.0 508 * 509 * @param BP_XProfile_Group $group Current BP_XProfile_Group object. 510 */ 511 do_action( 'xprofile_groups_deleted_group', $group ); 512 } 513 514 xprofile_admin_screen( $message, $type ); 515 } 516 } 517 518 /** 519 * Display the delete confirmation screen of profile data groups. 520 * 521 * @since 7.0.0 522 */ 523 function xprofile_admin_delete_group_screen( $group_id ) { 524 525 if ( ! bp_current_user_can( 'bp_moderate' ) ) { 526 die( '-1' ); 527 } 528 529 $group = new BP_XProfile_Group( $group_id ); 530 531 $base_url = remove_query_arg( array( 'mode', 'group_id', '_wpnonce' ), $_SERVER['REQUEST_URI'] ); ?> 532 533 <div class="wrap"> 534 <h1 class="wp-heading-inline"><?php esc_html_e( 'Delete Field Group', 'buddypress' ) ?></h1> 535 <hr class="wp-header-end"> 536 537 <p><?php esc_html_e( 'You are about to delete the following field group:', 'buddypress' ) ?></p> 538 539 <ul class="bp-xprofile-delete-group-list"> 540 <li><?php echo esc_html( $group->name ); ?></li> 541 </ul> 542 543 <p><strong><?php esc_html_e( 'This action cannot be undone.', 'buddypress' ) ?></strong></p> 544 545 <a class="button-primary" href="<?php echo esc_url( wp_nonce_url( add_query_arg( array( 'mode' => 'do_delete_group', 'group_id' => $group_id ), $base_url ), 'bp_xprofile_delete_group' ) ); ?>"><?php esc_html_e( 'Delete Permanently', 'buddypress' ) ?></a> 546 <a class="button" href="<?php echo esc_attr( $base_url ); ?>"><?php esc_html_e( 'Cancel', 'buddypress' ) ?></a> 547 </div> 548 549 <?php 550 } 551 552 /** 553 * Handles the adding or editing of profile field data for a user. 554 * 555 * @since 1.0.0 556 * 557 * @param int $group_id ID of the group. 558 * @param int|null $field_id ID of the field being managed. 559 */ 560 function xprofile_admin_manage_field( $group_id, $field_id = null ) { 561 global $wpdb, $message, $groups; 562 563 $bp = buddypress(); 564 565 if ( is_null( $field_id ) ) { 566 $field = new BP_XProfile_Field(); 567 } else { 568 $field = xprofile_get_field( $field_id, null, false ); 569 } 570 571 $field->group_id = $group_id; 572 573 if ( isset( $_POST['saveField'] ) ) { 574 575 // Check nonce. 576 check_admin_referer( 'bp_xprofile_admin_field', 'bp_xprofile_admin_field' ); 577 578 if ( BP_XProfile_Field::admin_validate() ) { 579 $field->is_required = $_POST['required']; 580 $field->type = $_POST['fieldtype']; 581 $field->name = $_POST['title']; 582 583 /* 584 * By default a Textbox field is created. To run field type's feature 585 * checks we need to set it to what it really is early. 586 */ 587 if ( is_null( $field_id ) ) { 588 $field_type = bp_xprofile_create_field_type( $field->type ); 589 590 // If it's a placeholder, then the field type is not registered. 591 if ( ! $field_type instanceof BP_XProfile_Field_Type_Placeholder ) { 592 $field->type_obj = $field_type; 593 } 594 } 595 596 if ( ! $field->field_type_supports( 'required' ) ) { 597 $field->is_required = "0"; 598 } 599 600 if ( ! empty( $_POST['description'] ) ) { 601 $field->description = $_POST['description']; 602 } else { 603 $field->description = ''; 604 } 605 606 if ( ! empty( $_POST["sort_order_{$field->type}"] ) ) { 607 $field->order_by = $_POST["sort_order_{$field->type}"]; 608 } 609 610 $field->field_order = $wpdb->get_var( $wpdb->prepare( "SELECT field_order FROM {$bp->profile->table_name_fields} WHERE id = %d", $field_id ) ); 611 if ( ! is_numeric( $field->field_order ) || is_wp_error( $field->field_order ) ) { 612 $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 ) ); 613 $field->field_order++; 614 } 615 616 // For new profile fields, set the $field_id. For existing profile 617 // fields, this will overwrite $field_id with the same value. 618 $field_id = $field->save(); 619 620 if ( empty( $field_id ) ) { 621 $message = __( 'There was an error saving the field. Please try again.', 'buddypress' ); 622 $type = 'error'; 623 } else { 624 $message = __( 'The field was saved successfully.', 'buddypress' ); 625 $type = 'success'; 626 627 // @todo remove these old options. 628 if ( 1 == $field_id ) { 629 bp_update_option( 'bp-xprofile-fullname-field-name', $field->name ); 630 } 631 632 // Set member types. 633 if ( isset( $_POST['has-member-types'] ) ) { 634 $member_types = array(); 635 if ( isset( $_POST['member-types'] ) ) { 636 $member_types = stripslashes_deep( $_POST['member-types'] ); 637 } 638 639 $field->set_member_types( $member_types ); 640 } 641 642 // Validate default visibility. 643 if ( ! empty( $_POST['default-visibility'] ) && in_array( $_POST['default-visibility'], wp_list_pluck( bp_xprofile_get_visibility_levels(), 'id' ) ) ) { 644 $default_visibility = $_POST['default-visibility']; 645 646 if ( ! $field->field_type_supports( 'allow_custom_visibility' ) ) { 647 $default_visibility = 'public'; 648 $available_visibility_levels = bp_xprofile_get_visibility_levels(); 649 650 if ( isset( $field->type_obj->visibility ) && in_array( $field->type_obj->visibility, array_keys( $available_visibility_levels ), true ) ) { 651 $default_visibility = $field->type_obj->visibility; 652 } 653 } 654 655 bp_xprofile_update_field_meta( $field_id, 'default_visibility', $default_visibility ); 656 } 657 658 // Validate custom visibility. 659 if ( ! empty( $_POST['allow-custom-visibility'] ) && in_array( $_POST['allow-custom-visibility'], array( 'allowed', 'disabled' ) ) ) { 660 $allow_custom_visibility = $_POST['allow-custom-visibility']; 661 662 if ( ! $field->field_type_supports( 'allow_custom_visibility' ) ) { 663 $allow_custom_visibility = 'disabled'; 664 } 665 666 bp_xprofile_update_field_meta( $field_id, 'allow_custom_visibility', $allow_custom_visibility ); 667 } 668 669 // Validate signup. 670 if ( $field->field_type_supports( 'signup_position' ) ) { 671 if ( ! empty( $_POST['signup-position'] ) ) { 672 bp_xprofile_update_field_meta( $field_id, 'signup_position', (int) $_POST['signup-position'] ); 673 } else { 674 bp_xprofile_delete_meta( $field_id, 'field', 'signup_position' ); 675 } 676 } 677 678 $do_autolink = ''; 679 if ( $field->field_type_supports( 'do_autolink' ) && isset( $_POST['do_autolink'] ) && $_POST['do_autolink'] ) { 680 $do_autolink = wp_unslash( $_POST['do_autolink'] ); 681 } 682 683 // Save autolink settings. 684 if ( 'on' === $do_autolink ) { 685 bp_xprofile_update_field_meta( $field_id, 'do_autolink', 'on' ); 686 } else { 687 bp_xprofile_update_field_meta( $field_id, 'do_autolink', 'off' ); 688 } 689 690 if ( $field->type_obj->do_settings_section() ) { 691 $settings = isset( $_POST['field-settings'] ) ? wp_unslash( $_POST['field-settings'] ) : array(); 692 $field->admin_save_settings( $settings ); 693 } 694 695 /** 696 * Fires at the end of the process to save a field for a user, if successful. 697 * 698 * @since 1.0.0 699 * 700 * @param BP_XProfile_Field $field Current BP_XProfile_Field object. 701 */ 702 do_action( 'xprofile_fields_saved_field', $field ); 703 704 $groups = bp_xprofile_get_groups(); 705 } 706 707 xprofile_admin_screen( $message, $type ); 708 709 } else { 710 $field->render_admin_form( $message ); 711 } 712 } else { 713 $field->render_admin_form(); 714 } 715 } 716 717 /** 718 * Handles the deletion of a profile field (or field option). 719 * 720 * @since 1.0.0 721 * 722 * @global string $message The feedback message to show. 723 * @global string $type The type of feedback message to show. 724 * 725 * @param int $field_id The field to delete. 726 * @param string $field_type The type of field being deleted. 727 * @param bool $delete_data Should the field data be deleted too. 728 */ 729 function xprofile_admin_delete_field( $field_id, $field_type = 'field', $delete_data = false ) { 730 global $message, $type; 731 732 check_admin_referer( 'bp_xprofile_delete_field-' . $field_id, 'bp_xprofile_delete_field' ); 733 734 $mode = ! empty( $_GET['mode'] ) ? sanitize_key( $_GET['mode'] ) : false; 735 736 // Switch type to 'option' if type is not 'field'. 737 // @todo trust this param. 738 $field_type = ( 'field' == $field_type ) ? __( 'field', 'buddypress' ) : __( 'option', 'buddypress' ); 739 740 // Display the field/option delete confirmation screen. 741 if ( in_array( $mode, array( 'delete_field', 'delete_option' ) ) ) { 742 xprofile_admin_delete_field_screen( $field_id, $field_type ); 743 744 // Handle the deletion of field 745 } else { 746 $field = xprofile_get_field( $field_id, null, false ); 747 748 if ( !$field->delete( (bool) $delete_data ) ) { 749 /* translators: %s: the field type */ 750 $message = sprintf( __( 'There was an error deleting the %s. Please try again.', 'buddypress' ), $field_type ); 751 $type = 'error'; 752 } else { 753 /* translators: %s: the field type */ 754 $message = sprintf( __( 'The %s was deleted successfully!', 'buddypress' ), $field_type ); 755 $type = 'success'; 756 757 /** 758 * Fires at the end of the field deletion process, if successful. 759 * 760 * @since 1.0.0 761 * 762 * @param BP_XProfile_Field $field Current BP_XProfile_Field object. 763 */ 764 do_action( 'xprofile_fields_deleted_field', $field ); 765 } 766 767 xprofile_admin_screen( $message, $type ); 768 } 769 } 770 771 /** 772 * Display the delete confirmation screen of xprofile field/option. 773 * 774 * @since 7.0.0 775 */ 776 function xprofile_admin_delete_field_screen( $field_id, $field_type ) { 777 if ( ! bp_current_user_can( 'bp_moderate' ) ) { 778 die( '-1' ); 779 } 780 781 $field = xprofile_get_field( $field_id, null, false ); 782 783 $base_url = remove_query_arg( array( 'mode', 'field_id', 'bp_xprofile_delete_field' ), $_SERVER['REQUEST_URI'] ); ?> 784 785 <div class="wrap"> 786 <h1 class="wp-heading-inline"> 787 <?php 788 printf( 789 /* translators: %s is the field type name. */ 790 esc_html__( 'Delete %s', 'buddypress' ), 791 $field_type 792 ); 793 ?> 794 </h1> 795 796 <hr class="wp-header-end"> 797 798 <p> 799 <?php 800 printf( 801 /* translators: %s is the field type name. */ 802 esc_html__( 'You are about to delete the following %s:', 'buddypress' ), 803 $field_type 804 ); 805 ?> 806 </p> 807 808 <ul class="bp-xprofile-delete-group-list"> 809 <li><?php echo esc_html( $field->name ); ?></li> 810 </ul> 811 812 <p><strong><?php esc_html_e( 'This action cannot be undone.', 'buddypress' ); ?></strong></p> 813 814 <a class="button-primary" href="<?php echo esc_url( wp_nonce_url( add_query_arg( array( 'mode' => 'do_delete_field', 'field_id' => $field_id ), $base_url ), 'bp_xprofile_delete_field-' . $field_id, 'bp_xprofile_delete_field' ) ); ?>"><?php esc_html_e( 'Delete Permanently', 'buddypress' ); ?></a> 815 <a class="button" href="<?php echo esc_attr( $base_url ); ?>"><?php esc_html_e( 'Cancel', 'buddypress' ); ?></a> 816 </div> 817 818 <?php 819 } 820 821 822 823 /** 824 * Handles the ajax reordering of fields within a group. 825 * 826 * @since 1.0.0 827 * @since 8.0.0 Returns a JSON object. 828 */ 829 function xprofile_ajax_reorder_fields() { 830 // Check the nonce. 831 check_admin_referer( 'bp_reorder_fields', '_wpnonce_reorder_fields' ); 832 833 if ( empty( $_POST['field_order'] ) ) { 834 return wp_send_json_error(); 835 } 836 837 $field_group_id = $_POST['field_group_id']; 838 $group_tab = ''; 839 840 if ( isset( $_POST['group_tab'] ) && $_POST['group_tab'] ) { 841 $group_tab = wp_unslash( $_POST['group_tab'] ); 842 } 843 844 if ( 'signup-fields' === $field_group_id ) { 845 parse_str( $_POST['field_order'], $order ); 846 $fields = (array) $order['draggable_signup_field']; 847 $fields = array_map( 'intval', $fields ); 848 849 if ( isset( $_POST['new_signup_field_id'] ) && $_POST['new_signup_field_id'] ) { 850 parse_str( $_POST['new_signup_field_id'], $signup_field ); 851 $signup_fields = (array) $signup_field['draggable_signup_field']; 852 } 853 854 // Adding a new field to the registration form. 855 if ( 'signup-group' === $group_tab ) { 856 $field_id = (int) reset( $signup_fields ); 857 858 // Load the field. 859 $field = xprofile_get_field( $field_id, null, false ); 860 861 if ( $field instanceof BP_XProfile_Field ) { 862 // The field doesn't support the feature, stop right away! 863 if ( ! $field->field_type_supports( 'signup_position' ) ) { 864 wp_send_json_error( 865 array( 866 'message' => __( 'This field cannot be inserted into the registration form.', 'buddypress' ), 867 ) 868 ); 869 } 870 871 $signup_position = bp_xprofile_get_meta( $field->id, 'field', 'signup_position' ); 872 873 if ( ! $signup_position ) { 874 $position = array_search( $field->id, $fields, true ); 875 if ( false !== $position ) { 876 $position += 1; 877 } else { 878 $position = 1; 879 } 880 881 // Set the signup position. 882 bp_xprofile_update_field_meta( $field->id, 'signup_position', $position ); 883 884 // Get the real Group object. 885 $group = xprofile_get_field_group( $field->id ); 886 887 // Gets the HTML Output of the signup field. 888 $signup_field = bp_xprofile_admin_get_signup_field( $field, $group ); 889 890 /** 891 * Fires once a signup field has been inserted. 892 * 893 * @since 8.0.0 894 */ 895 do_action( 'bp_xprofile_inserted_signup_field' ); 896 897 // Send the signup field to output. 898 wp_send_json_success( 899 array( 900 'signup_field' => $signup_field, 901 'field_id' => $field->id, 902 ) 903 ); 904 } else { 905 wp_send_json_error( 906 array( 907 'message' => __( 'This field has been already added to the registration form.', 'buddypress' ), 908 ) 909 ); 910 } 911 912 } else { 913 wp_send_json_error(); 914 } 915 } else { 916 // it's a sort operation. 917 foreach ( $fields as $position => $field_id ) { 918 bp_xprofile_update_field_meta( (int) $field_id, 'signup_position', (int) $position + 1 ); 919 } 920 921 /** 922 * Fires once the signup fields have been reordered. 923 * 924 * @since 8.0.0 925 */ 926 do_action( 'bp_xprofile_reordered_signup_fields' ); 927 928 wp_send_json_success(); 929 } 930 } else { 931 /** 932 * @todo there's something going wrong here. 933 * moving a field to another tab when there's only the fullname field fails. 934 */ 935 parse_str( $_POST['field_order'], $order ); 936 $fields = (array) $order['draggable_field']; 937 938 foreach ( $fields as $position => $field_id ) { 939 xprofile_update_field_position( (int) $field_id, (int) $position, (int) $field_group_id ); 940 } 941 942 wp_send_json_success(); 943 } 944 } 945 add_action( 'wp_ajax_xprofile_reorder_fields', 'xprofile_ajax_reorder_fields' ); 946 947 /** 948 * Removes a field from signup fields. 949 * 950 * @since 8.0.0 951 */ 952 function bp_xprofile_ajax_remove_signup_field() { 953 // Check the nonce. 954 check_admin_referer( 'bp_reorder_fields', '_wpnonce_reorder_fields' ); 955 956 if ( ! isset( $_POST['signup_field_id'] ) || ! $_POST['signup_field_id'] ) { 957 return wp_send_json_error(); 958 } 959 960 $signup_field_id = (int) wp_unslash( $_POST['signup_field_id'] ); 961 962 // Validate the field ID. 963 $signup_position = bp_xprofile_get_meta( $signup_field_id, 'field', 'signup_position' ); 964 965 if ( ! $signup_position ) { 966 wp_send_json_error(); 967 } 968 969 bp_xprofile_delete_meta( $signup_field_id, 'field', 'signup_position' ); 970 971 /** 972 * Fires when a signup field is removed from the signup form. 973 * 974 * @since 8.0.0 975 */ 976 do_action( 'bp_xprofile_removed_signup_field' ); 977 978 wp_send_json_success(); 979 } 980 add_action( 'wp_ajax_xprofile_remove_signup_field', 'bp_xprofile_ajax_remove_signup_field' ); 981 982 /** 983 * Handles the reordering of field groups. 984 * 985 * @since 1.5.0 986 */ 987 function xprofile_ajax_reorder_field_groups() { 988 989 // Check the nonce. 990 check_admin_referer( 'bp_reorder_groups', '_wpnonce_reorder_groups' ); 991 992 if ( empty( $_POST['group_order'] ) ) { 993 return false; 994 } 995 996 parse_str( $_POST['group_order'], $order ); 997 998 foreach ( (array) $order['group'] as $position => $field_group_id ) { 999 xprofile_update_field_group_position( (int) $field_group_id, (int) $position ); 1000 } 1001 } 1002 add_action( 'wp_ajax_xprofile_reorder_groups', 'xprofile_ajax_reorder_field_groups' ); 1003 1004 /** 1005 * Handles the WYSIWYG display of each profile field on the edit screen. 1006 * 1007 * @since 1.5.0 1008 * @since 8.0.0 Adds the `$is_signup` parameter. 1009 * 1010 * @param BP_XProfile_Field $admin_field Admin field. 1011 * @param object $admin_group Admin group object. 1012 * @param string $class Classes to append to output. 1013 * @param bool $is_signup Whether the admin field output is made inside the signup group. 1014 */ 1015 function xprofile_admin_field( $admin_field, $admin_group, $class = '', $is_signup = false ) { 1016 global $field; 1017 1018 $field = $admin_field; 1019 $fieldset_id = sprintf( 'draggable_field_%d', $field->id ); 1020 1021 // Users admin URL. 1022 $url = bp_get_admin_url( 'users.php' ); 1023 1024 // Edit. 1025 $field_edit_url = add_query_arg( array( 1026 'page' => 'bp-profile-setup', 1027 'mode' => 'edit_field', 1028 'group_id' => (int) $field->group_id, 1029 'field_id' => (int) $field->id 1030 ), $url ); 1031 1032 // Delete. 1033 if ( $field->can_delete ) { 1034 $field_delete_url = add_query_arg( array( 1035 'page' => 'bp-profile-setup', 1036 'mode' => 'delete_field', 1037 'field_id' => (int) $field->id 1038 ), $url . '#tabs-' . (int) $field->group_id ); 1039 } 1040 1041 // Avoid duplicate IDs into the signup group. 1042 if ( $is_signup ) { 1043 $fieldset_id = sprintf( 'draggable_signup_field_%d', $field->id ); 1044 } 1045 ?> 1046 1047 <fieldset id="<?php echo esc_attr( $fieldset_id ); ?>" class="sortable<?php echo ' ' . $field->type; if ( !empty( $class ) ) echo ' ' . $class; ?>"> 1048 <legend> 1049 <span> 1050 <?php bp_the_profile_field_name(); ?> 1051 1052 <?php if ( empty( $field->can_delete ) ) : ?><?php esc_html_e( '(Primary)', 'buddypress' ); endif; ?> 1053 <?php bp_the_profile_field_required_label(); ?> 1054 <?php if ( $field->get_signup_position() ) : ?> 1055 <span class="bp-signup-field-label"><?php esc_html_e( '(Sign-up)', 'buddypress' );?></span> 1056 <?php endif; ?> 1057 <?php if ( bp_get_member_types() ) : echo $field->get_member_type_label(); endif; ?> 1058 1059 <?php 1060 1061 /** 1062 * Fires at end of legend above the name field in base xprofile group. 1063 * 1064 * @since 2.2.0 1065 * 1066 * @param BP_XProfile_Field $field Current BP_XProfile_Field 1067 * object being rendered. 1068 */ 1069 do_action( 'xprofile_admin_field_name_legend', $field ); ?> 1070 </span> 1071 </legend> 1072 <div class="field-wrapper"> 1073 1074 <?php 1075 if ( in_array( $field->type, array_keys( bp_xprofile_get_field_types() ) ) ) { 1076 $field_type = bp_xprofile_create_field_type( $field->type ); 1077 $field_type->admin_field_html(); 1078 } else { 1079 1080 /** 1081 * Fires after the input if the current field is not in default field types. 1082 * 1083 * @since 1.5.0 1084 * 1085 * @param BP_XProfile_Field $field Current BP_XProfile_Field 1086 * object being rendered. 1087 * @param int $value Integer 1. 1088 */ 1089 do_action( 'xprofile_admin_field', $field, 1 ); 1090 } 1091 ?> 1092 1093 <?php if ( $field->description ) : ?> 1094 1095 <p class="description"><?php echo esc_attr( $field->description ); ?></p> 1096 1097 <?php endif; ?> 1098 1099 <div class="actions"> 1100 <a class="button edit" href="<?php echo esc_url( $field_edit_url ); ?>"><?php _ex( 'Edit', 'Edit field link', 'buddypress' ); ?></a> 1101 1102 <?php if ( $field->can_delete && ! $is_signup ) : ?> 1103 1104 <div class="delete-button"> 1105 <a class="confirm submit-delete deletion" href="<?php echo esc_url( wp_nonce_url( $field_delete_url, 'bp_xprofile_delete_field-' . $field->id, 'bp_xprofile_delete_field' ) ); ?>"><?php _ex( 'Delete', 'Delete field link', 'buddypress' ); ?></a> 1106 </div> 1107 1108 <?php endif; ?> 1109 1110 <?php if ( $field->can_delete && $is_signup ) : ?> 1111 1112 <div class="delete-button"> 1113 <a class="submit-delete removal" href="<?php echo esc_attr( sprintf( '#remove_field-%d', $field->id ) ); ?>"><?php echo esc_html_x( 'Remove', 'Remove field link', 'buddypress' ); ?></a> 1114 </div> 1115 1116 <?php endif; ?> 1117 1118 <?php 1119 1120 /** 1121 * Fires at end of field management links in xprofile management admin. 1122 * 1123 * @since 2.2.0 1124 * 1125 * @param BP_XProfile_Group $group BP_XProfile_Group object 1126 * for the current group. 1127 */ 1128 do_action( 'xprofile_admin_field_action', $field ); ?> 1129 1130 </div> 1131 </div> 1132 </fieldset> 1133 <?php 1134 } 1135 1136 /** 1137 * Handles the WYSIWYG display of signup profile fields on the edit screen. 1138 * 1139 * @since 8.0.0 1140 * 1141 * @param BP_XProfile_Field $signup_field The field to use into the signup form. 1142 * @param object $field_group The real field group object. 1143 * @param string $class Classes to append to output. 1144 * @param bool $echo Whether to return or display the HTML output. 1145 * @return string The HTML output. 1146 */ 1147 function bp_xprofile_admin_get_signup_field( $signup_field, $field_group = null, $class = '', $echo = false ) { 1148 add_filter( 'bp_get_the_profile_field_input_name', 'bp_get_the_profile_signup_field_input_name' ); 1149 1150 if ( ! $echo ) { 1151 // Set up an output buffer. 1152 ob_start(); 1153 xprofile_admin_field( $signup_field, $field_group, $class, true ); 1154 $output = ob_get_contents(); 1155 ob_end_clean(); 1156 } else { 1157 xprofile_admin_field( $signup_field, $field_group, $class, true ); 1158 } 1159 1160 remove_filter( 'bp_get_the_profile_field_input_name', 'bp_get_the_profile_signup_field_input_name' ); 1161 1162 if ( ! $echo ) { 1163 return $output; 1164 } 1165 } 1166 1167 /** 1168 * Print <option> elements containing the xprofile field types. 1169 * 1170 * @since 2.0.0 1171 * 1172 * @param string $select_field_type The name of the field type that should be selected. 1173 * Will defaults to "textbox" if NULL is passed. 1174 */ 1175 function bp_xprofile_admin_form_field_types( $select_field_type ) { 1176 $categories = array(); 1177 1178 if ( is_null( $select_field_type ) ) { 1179 $select_field_type = 'textbox'; 1180 } 1181 1182 // Sort each field type into its category. 1183 foreach ( bp_xprofile_get_field_types() as $field_name => $field_class ) { 1184 $field_type_obj = new $field_class; 1185 $the_category = $field_type_obj->category; 1186 1187 // Fallback to a catch-all if category not set. 1188 if ( ! $the_category ) { 1189 $the_category = _x( 'Other', 'xprofile field type category', 'buddypress' ); 1190 } 1191 1192 if ( isset( $categories[$the_category] ) ) { 1193 $categories[$the_category][] = array( $field_name, $field_type_obj ); 1194 } else { 1195 $categories[$the_category] = array( array( $field_name, $field_type_obj ) ); 1196 } 1197 } 1198 1199 // Sort the categories alphabetically. ksort()'s SORT_NATURAL is only in PHP >= 5.4 :((. 1200 uksort( $categories, 'strnatcmp' ); 1201 1202 // Loop through each category and output form <options>. 1203 foreach ( $categories as $category => $fields ) { 1204 printf( '<optgroup label="%1$s">', esc_attr( $category ) ); // Already i18n'd in each profile type class. 1205 1206 // Sort these fields types alphabetically. 1207 uasort( $fields, function( $a, $b ) { return strnatcmp( $a[1]->name, $b[1]->name ); } ); 1208 1209 foreach ( $fields as $field_type_obj ) { 1210 $field_name = $field_type_obj[0]; 1211 $field_type_obj = $field_type_obj[1]; 1212 1213 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 ) ); 1214 } 1215 1216 printf( '</optgroup>' ); 1217 } 1218 } 1219 1220 // Load the xprofile user admin. 1221 add_action( 'bp_init', array( 'BP_XProfile_User_Admin', 'register_xprofile_user_admin' ), 11 );
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Nov 21 01:00:57 2024 | Cross-referenced by PHPXref 0.7.1 |