Ticket #8139: 8139.02.diff
File 8139.02.diff, 122.1 KB (added by , 4 years ago) |
---|
-
src/bp-core/admin/bp-core-admin-functions.php
diff --git src/bp-core/admin/bp-core-admin-functions.php src/bp-core/admin/bp-core-admin-functions.php index b50ad98c6..8f4a98a2b 100644
function bp_core_activation_notice() { 278 278 279 279 // Activate and Register are special cases. They are not components but they need WP pages. 280 280 // If user registration is disabled, we can skip this step. 281 if ( bp_get_signup_allowed() ) {281 if ( bp_get_signup_allowed() || bp_get_members_invitations_allowed() ) { 282 282 $wp_page_components[] = array( 283 283 'id' => 'activate', 284 284 'name' => __( 'Activate', 'buddypress' ), -
src/bp-core/admin/bp-core-admin-settings.php
diff --git src/bp-core/admin/bp-core-admin-settings.php src/bp-core/admin/bp-core-admin-settings.php index cf8d43468..550e6a26a 100644
function bp_admin_setting_callback_cover_image_uploads() { 182 182 <?php 183 183 } 184 184 185 /** 186 * Allow members to invite non-members to the network. 187 * 188 * @since 7.0.0 189 */ 190 function bp_admin_setting_callback_members_invitations() { 191 ?> 192 <input id="bp-enable-members-invitations" name="bp-enable-members-invitations" type="checkbox" value="1" <?php checked( bp_get_members_invitations_allowed() ); ?> /> 193 <label for="bp-enable-members-invitations"><?php _e( 'Allow registered members to invite people to join this network', 'buddypress' ); ?></label> 194 <?php if ( ! bp_get_signup_allowed() ) : ?> 195 <p class="description"><?php _e( 'Public registration is currently disabled. However, invitees will still be able to register if network invitations are enabled.', 'buddypress' ); ?></p> 196 <?php endif; ?> 197 <?php 198 /** 199 * Fires after the output of the invitations settings section. 200 * 201 * @since 7.0.0 202 */ 203 do_action( 'bp_admin_settings_after_members_invitations' ); 204 } 205 185 206 /** XProfile ******************************************************************/ 186 207 187 208 /** -
src/bp-core/admin/bp-core-admin-slugs.php
diff --git src/bp-core/admin/bp-core-admin-slugs.php src/bp-core/admin/bp-core-admin-slugs.php index 8831e7189..3b85b950f 100644
function bp_core_admin_slugs_options() { 186 186 187 187 <h3><?php _e( 'Registration', 'buddypress' ); ?></h3> 188 188 189 <?php if ( bp_get_signup_allowed() ) : ?>189 <?php if ( bp_get_signup_allowed() || bp_get_members_invitations_allowed() ) : ?> 190 190 <p><?php _e( 'Associate WordPress Pages with the following BuddyPress Registration pages.', 'buddypress' ); ?></p> 191 191 <?php else : ?> 192 192 <?php if ( is_multisite() ) : ?> … … function bp_core_admin_slugs_options() { 209 209 <table class="form-table"> 210 210 <tbody> 211 211 212 <?php if ( bp_get_signup_allowed() ) : foreach ( $static_pages as $name => $label ) : ?>212 <?php if ( bp_get_signup_allowed() || bp_get_members_invitations_allowed() ) : foreach ( $static_pages as $name => $label ) : ?> 213 213 214 214 <tr valign="top"> 215 215 <th scope="row"> -
src/bp-core/bp-core-functions.php
diff --git src/bp-core/bp-core-functions.php src/bp-core/bp-core-functions.php index c1481135e..d626a38da 100644
function bp_core_add_page_mappings( $components, $existing = 'keep' ) { 693 693 694 694 // Register and Activate are not components, but need pages when 695 695 // registration is enabled. 696 if ( bp_get_signup_allowed() ) {696 if ( bp_get_signup_allowed() || bp_get_members_invitations_allowed() ) { 697 697 foreach ( array( 'register', 'activate' ) as $slug ) { 698 698 if ( ! isset( $pages[ $slug ] ) ) { 699 699 $pages_to_create[ $slug ] = $page_titles[ $slug ]; … … function bp_send_email( $email_type, $to, $args = array() ) { 3153 3153 // From, subject, content are set automatically. 3154 3154 if ( 'settings-verify-email-change' === $email_type && isset( $args['tokens']['displayname'] ) ) { 3155 3155 $email->set_to( $to, $args['tokens']['displayname'] ); 3156 // Emails sent to nonmembers will have no recipient.name populated. 3157 } else if ( 'bp-members-invitation' === $email_type ) { 3158 $email->set_to( $to, $to ); 3156 3159 } else { 3157 3160 $email->set_to( $to ); 3158 3161 } … … function bp_email_get_schema() { 3488 3491 /* translators: do not remove {} brackets or translate its contents. */ 3489 3492 'post_title' => __( '[{{{site.name}}}] You have an invitation to the group: "{{group.name}}"', 'buddypress' ), 3490 3493 /* translators: do not remove {} brackets or translate its contents. */ 3491 'post_content' => __( "<a href=\"{{{inviter.url}}}\">{{inviter.name}}</a> has invited you to join the group: "{{group.name}}".\n {{invite.message}}\n<a href=\"{{{invites.url}}}\">Go here to accept your invitation</a> or <a href=\"{{{group.url}}}\">visit the group</a> to learn more.", 'buddypress' ),3494 'post_content' => __( "<a href=\"{{{inviter.url}}}\">{{inviter.name}}</a> has invited you to join the group: "{{group.name}}".\n\n{{invite.message}}\n\n<a href=\"{{{invites.url}}}\">Go here to accept your invitation</a> or <a href=\"{{{group.url}}}\">visit the group</a> to learn more.", 'buddypress' ), 3492 3495 /* translators: do not remove {} brackets or translate its contents. */ 3493 'post_excerpt' => __( "{{inviter.name}} has invited you to join the group: \"{{group.name}}\".\n\n To accept your invitation, visit: {{{invites.url}}}\n\nTo learn more about the group, visit: {{{group.url}}}.\nTo view {{inviter.name}}'s profile, visit: {{{inviter.url}}}", 'buddypress' ),3496 'post_excerpt' => __( "{{inviter.name}} has invited you to join the group: \"{{group.name}}\".\n\n{{invite.message}}\n\nTo accept your invitation, visit: {{{invites.url}}}\n\nTo learn more about the group, visit: {{{group.url}}}.\nTo view {{inviter.name}}'s profile, visit: {{{inviter.url}}}", 'buddypress' ), 3494 3497 ), 3495 3498 'groups-member-promoted' => array( 3496 3499 /* translators: do not remove {} brackets or translate its contents. */ … … function bp_email_get_schema() { 3540 3543 /* translators: do not remove {} brackets or translate its contents. */ 3541 3544 'post_excerpt' => __( "Your membership request for the group \"{{group.name}}\" has been rejected.\n\nTo request membership again, visit: {{{group.url}}}", 'buddypress' ), 3542 3545 ), 3546 'bp-members-invitation' => array( 3547 /* translators: do not remove {} brackets or translate its contents. */ 3548 'post_title' => __( '[{{{site.name}}}] You have an invitation to the site: "{{network.name}}"', 'buddypress' ), 3549 /* translators: do not remove {} brackets or translate its contents. */ 3550 'post_content' => __( "<a href=\"{{{inviter.url}}}\">{{inviter.name}}</a> has invited you to join the site: "{{network.name}}".\n\n{{invite.message}}\n\n<a href=\"{{{invites.url}}}\">Go here to accept your invitation</a> or <a href=\"{{{network.url}}}\">visit the site</a> to learn more.", 'buddypress' ), 3551 /* translators: do not remove {} brackets or translate its contents. */ 3552 'post_excerpt' => __( "{{inviter.name}} has invited you to join the site: \"{{network.name}}\".\n\n{{invite.message}}\n\nTo accept your invitation, visit: {{{invites.url}}}\n\nTo learn more about the site, visit: {{{network.url}}}.\nTo view {{inviter.name}}'s profile, visit: {{{inviter.url}}}", 'buddypress' ), 3553 ), 3543 3554 ) ); 3544 3555 } 3545 3556 … … function bp_email_get_type_schema( $field = 'description' ) { 3681 3692 ), 3682 3693 ); 3683 3694 3695 $members_invitation = array( 3696 'description' => __( 'A site member has sent a site invitation to the recipient.', 'buddypress' ), 3697 'unsubscribe' => array( 3698 'meta_key' => 'notification_bp_members_invite', 3699 'message' => __( 'You will no longer receive emails when you are invited to join a site.', 'buddypress' ), 3700 ), 3701 ); 3702 3684 3703 $types = array( 3685 3704 'activity-comment' => $activity_comment, 3686 3705 'activity-comment-author' => $activity_comment_author, … … function bp_email_get_type_schema( $field = 'description' ) { 3698 3717 'settings-verify-email-change' => $settings_verify_email_change, 3699 3718 'groups-membership-request-accepted' => $groups_membership_request_accepted, 3700 3719 'groups-membership-request-rejected' => $groups_membership_request_rejected, 3720 'bp-members-invitation' => $members_invitation, 3701 3721 ); 3702 3722 3703 3723 if ( $field !== 'all' ) { -
src/bp-core/bp-core-template.php
diff --git src/bp-core/bp-core-template.php src/bp-core/bp-core-template.php index 9fc92249a..c462cc799 100644
function bp_is_settings_component() { 2247 2247 return (bool) bp_is_current_component( 'settings' ); 2248 2248 } 2249 2249 2250 /** 2251 * Check whether the current page is an Invitations screen. 2252 * 2253 * @since 6.0.0 2254 * 2255 * @return bool True if the current page is an Invitations screen. 2256 */ 2257 function bp_is_community_invitations_screen() { 2258 return (bool) bp_is_current_component( bp_get_members_invitations_slug() ); 2259 } 2260 2250 2261 /** 2251 2262 * Is the current component an active core component? 2252 2263 * … … function bp_is_user_settings_profile() { 2647 2658 return (bool) ( bp_is_user_settings() && bp_is_current_action( 'profile' ) ); 2648 2659 } 2649 2660 2661 /** 2662 * Is the current page a user's community invitations page? 2663 * 2664 * Eg http://example.com/members/cassie/invitations/ (or a subpage thereof). 2665 * 2666 * @since 7.0.0 2667 * 2668 * @return bool True if the current page is a user's community invitations page. 2669 */ 2670 function bp_is_user_members_invitations() { 2671 return (bool) ( bp_is_user() && bp_is_community_invitations_screen() ); 2672 } 2673 2674 /** 2675 * Is the current page a user's List Invites page? 2676 * 2677 * Eg http://example.com/members/cassie/invitations/list-invites/. 2678 * 2679 * @since 7.0.0 2680 * 2681 * @return bool True if the current page is a user's List Invites page. 2682 */ 2683 function bp_is_user_members_invitations_list() { 2684 return (bool) ( bp_is_user_members_invitations() && bp_is_current_action( 'list-invites' ) ); 2685 } 2686 2687 /** 2688 * Is the current page a user's Send Invites page? 2689 * 2690 * Eg http://example.com/members/cassie/invitations/send-invites/. 2691 * 2692 * @since 7.0.0 2693 * 2694 * @return bool True if the current page is a user's Send Invites page. 2695 */ 2696 function bp_is_user_members_invitations_send_screen() { 2697 return (bool) ( bp_is_user_members_invitations() && bp_is_current_action( 'send-invites' ) ); 2698 } 2699 2650 2700 /** Groups ********************************************************************/ 2651 2701 2652 2702 /** -
src/bp-core/classes/class-bp-admin.php
diff --git src/bp-core/classes/class-bp-admin.php src/bp-core/classes/class-bp-admin.php index 5457a816c..36ec1e0f3 100644
class BP_Admin { 409 409 register_setting( 'buddypress', 'bp-disable-cover-image-uploads', 'intval' ); 410 410 } 411 411 412 // Community Invitations. 413 if ( bp_is_active( 'members', 'invitations' ) ) { 414 add_settings_field( 'bp-enable-members-invitations', __( 'Invitations', 'buddypress' ), 'bp_admin_setting_callback_members_invitations', 'buddypress', 'bp_members' ); 415 register_setting( 'buddypress', 'bp-enable-members-invitations', 'intval' ); 416 } 417 412 418 /* XProfile Section **************************************************/ 413 419 414 420 if ( bp_is_active( 'xprofile' ) ) { -
src/bp-core/classes/class-bp-invitation-manager.php
diff --git src/bp-core/classes/class-bp-invitation-manager.php src/bp-core/classes/class-bp-invitation-manager.php index 904fe3e4e..a8a128bfb 100644
abstract class BP_Invitation_Manager { 99 99 return false; 100 100 } 101 101 102 // If an email address is specified, it must be a valid email address. 103 if ( $r['invitee_email'] && ! is_email( $r['invitee_email'] ) ) { 104 return false; 105 } 106 102 107 /** 103 108 * Is this user allowed to extend invitations in this situation? 104 109 * … … abstract class BP_Invitation_Manager { 156 161 * 157 162 * @param int $invitation_id ID of invitation to send. 158 163 * 159 * @return int|bool The number of rows updated, or false on error.164 * @return bool The result of `run_send_action()`. 160 165 */ 161 166 public function send_invitation_by_id( $invitation_id = 0 ) { 162 167 $updated = false; … … abstract class BP_Invitation_Manager { 194 199 } 195 200 196 201 // Perform the send action. 197 $ this->run_send_action( $invitation );202 $success = $this->run_send_action( $invitation ); 198 203 199 $updated = BP_Invitation::mark_sent( $invitation->id ); 204 if ( $success ) { 205 BP_Invitation::mark_sent( $invitation->id ); 206 } 200 207 201 return $ updated;208 return $success; 202 209 } 203 210 204 211 /** … … abstract class BP_Invitation_Manager { 307 314 * 308 315 * @param int $request_id ID of request to send. 309 316 * 310 * @return int|bool The number of rows updated, or false on error.317 * @return bool The result of `run_send_action()`. 311 318 */ 312 319 public function send_request_notification_by_id( $request_id = 0 ) { 313 320 $updated = false; … … abstract class BP_Invitation_Manager { 340 347 } 341 348 342 349 // Perform the send action. 343 $ this->run_send_action( $request );350 $success = $this->run_send_action( $request ); 344 351 345 $updated = BP_Invitation::mark_sent( $request->id ); 352 if ( $success ) { 353 BP_Invitation::mark_sent( $request->id ); 354 } 346 355 347 return $ updated;356 return $success; 348 357 } 349 358 350 359 /** Retrieve ******************************************************************/ … … abstract class BP_Invitation_Manager { 381 390 return BP_Invitation::get( $args ); 382 391 } 383 392 393 /** 394 * Get a count of the number of invitations that match provided filter parameters. 395 * 396 * @since 7.0.0 397 * 398 * @see BP_Invitation::get_total_count() for a description of accepted parameters. 399 * 400 * @return int Total number of invitations. 401 */ 402 public function get_invitations_total_count( $args = array() ) { 403 // Default to returning invitations, not requests. 404 if ( empty( $args['type'] ) ) { 405 $args['type'] = 'invite'; 406 } 407 // Use the class_name property value. 408 $args['class'] = $this->class_name; 409 410 return BP_Invitation::get_total_count( $args ); 411 } 412 384 413 /** 385 414 * Get requests, based on provided filter parameters. 386 415 * … … abstract class BP_Invitation_Manager { 688 717 ) ); 689 718 } 690 719 720 /** 721 * Delete an invitation by id. 722 * 723 * @since 7.0.0 724 * 725 * @param int $id ID of the invitation to delete. 726 * @return int|bool Number of rows deleted on success, false on failure. 727 */ 728 public function delete_by_id( $id ) { 729 // Ensure that the invitation exists and was created by this class. 730 $invite = new BP_Invitation( $id ); 731 if ( ! $invite->id || sanitize_key( $this->class_name ) !== $invite->class ) { 732 return false; 733 } 734 735 return BP_Invitation::delete_by_id( $id ); 736 } 737 738 739 691 740 /** 692 741 * This is where custom actions are added (in child classes) 693 742 * to determine whether an invitation should be allowed. -
src/bp-members/admin/bp-members-admin-classes.php
diff --git src/bp-members/admin/bp-members-admin-classes.php src/bp-members/admin/bp-members-admin-classes.php index 96e339e7a..4e2e79b54 100644
defined( 'ABSPATH' ) || exit; 12 12 13 13 if ( class_exists( 'WP_Users_List_Table' ) ) { 14 14 require dirname( dirname( __FILE__ ) ) . '/classes/class-bp-members-list-table.php'; 15 require dirname( dirname( __FILE__ ) ) . '/classes/class-bp-members-invitations-list-table.php'; 15 16 } 16 17 17 18 if ( class_exists( 'WP_MS_Users_List_Table' ) ) { -
src/bp-members/bp-members-filters.php
diff --git src/bp-members/bp-members-filters.php src/bp-members/bp-members-filters.php index 5575ebef2..40156dac9 100644
function bp_members_edit_profile_url( $url, $user_id, $scheme = 'admin' ) { 127 127 return apply_filters( 'bp_members_edit_profile_url', $profile_link, $url, $user_id, $scheme ); 128 128 } 129 129 add_filter( 'edit_profile_url', 'bp_members_edit_profile_url', 10, 3 ); 130 131 /** 132 * Filter the bp_user_can value to determine what the user can do in the members component. 133 * 134 * @since 7.0.0 135 * 136 * @param bool $retval Whether or not the current user has the capability. 137 * @param int $user_id 138 * @param string $capability The capability being checked for. 139 * @param int $site_id Site ID. Defaults to the BP root blog. 140 * @param array $args Array of extra arguments passed. 141 * 142 * @return bool 143 */ 144 function bp_members_user_can_filter( $retval, $user_id, $capability, $site_id, $args ) { 145 146 switch ( $capability ) { 147 case 'bp_members_manage_membership_requests': 148 $retval = bp_user_can( $user_id, 'bp_moderate' ); 149 break; 150 case 'bp_members_send_invitation': 151 // @todo Add restrictions? 152 if ( bp_get_members_invitations_allowed() ) { 153 $retval = true; 154 } 155 break; 156 case 'bp_members_receive_invitation': 157 if ( bp_get_members_invitations_allowed() ) { 158 $retval = true; 159 // The invited user must not already be a member of the network. 160 if ( empty( $args['invitee_email'] ) || false !== get_user_by( 'email', $args['invitee_email'] ) ) { 161 $retval = false; 162 } 163 // @TODO: The invited user must not have opted out from receiving invitations. 164 } 165 166 break; 167 } 168 169 return $retval; 170 171 } 172 add_filter( 'bp_user_can', 'bp_members_user_can_filter', 10, 5 ); 173 174 /** 175 * If the signup is the result of a member request, do not send the 176 * activation email. We will send the activation email once the 177 * the request has ben approved. 178 * 179 * @since 7.0.0 180 * 181 * @param array $usermeta The field attributes. 182 * 183 * @return array $usermeta The field attributes. 184 */ 185 function bp_members_invitations_prevent_activation_emails_for_requests( $usermeta ) { 186 // Stop the activation email from being sent if registration is by request only. 187 // if "anyone can join is not true," 188 // @TODO 189 if ( true ) { 190 191 } 192 return $usermeta; 193 } 194 add_filter( 'bp_signup_usermeta', 'bp_members_invitations_prevent_activation_emails_for_requests', 10, 1 ); 195 196 /** 197 * Do not allow the new user to change the email address 198 * if they are accepting a community invitation. 199 * 200 * @since 7.0.0 201 * 202 * @param array $attributes The field attributes. 203 * @param string $name The field name. 204 * 205 * @return array $attributes The field attributes. 206 */ 207 function bp_members_invitations_make_registration_email_input_readonly_if_invite( $attributes, $name ) { 208 if ( 'email' === $name && bp_get_members_invitations_allowed() ) { 209 $invite = bp_get_members_invitation_from_request(); 210 if ( $invite->id ) { 211 $attributes['readonly'] = 'readonly'; 212 } 213 } 214 return $attributes; 215 } 216 add_filter( 'bp_get_form_field_attributes', 'bp_members_invitations_make_registration_email_input_readonly_if_invite', 10, 2 ); 217 218 /** 219 * Provide a more-specific welcome message if the new user 220 * is accepting a network invitation. 221 * 222 * @since 7.0.0 223 * 224 * @return string $message The message text. 225 */ 226 function bp_members_invitations_get_registration_welcome_message() { 227 $message = ''; 228 if ( ! bp_get_members_invitations_allowed() ) { 229 return $message; 230 } 231 $invite = bp_get_members_invitation_from_request(); 232 if ( ! $invite->id ) { 233 return $message; 234 } 235 236 // Fetch the display names of all inviters to personalize the welcome message. 237 $all_invites = bp_members_invitations_get_invites( 238 array( 239 'invitee_email' => $invite->invitee_email, 240 'invite_sent' => 'sent', 241 ) 242 ); 243 $inviters = array(); 244 foreach ( $all_invites as $inv ) { 245 $inviters[] = bp_core_get_user_displayname( $inv->inviter_id ); 246 } 247 248 if ( ! empty( $inviters ) ) { 249 $message = sprintf( _n( 'Welcome! You’ve been invited to join the site by the following user: %s. ', 'Welcome! You’ve been invited to join the site by the following users: %s. ', count( $inviters ), 'buddypress' ), implode( ', ', $inviters ) ); 250 } else { 251 $message = __( 'Welcome! You’ve been invited to join the site. ', 'buddypress' ); 252 } 253 return $message; 254 } 255 256 /** 257 * Provide a more-specific "registration is disabled" message 258 * if registration is available by invitation only. 259 * Also provide failure note if new user is trying to accept 260 * a network invitation but there's a problem. 261 * 262 * @since 7.0.0 263 * 264 * @return string $message The message text. 265 */ 266 function bp_members_invitations_get_modified_registration_disabled_message() { 267 $message = ''; 268 if ( bp_get_members_invitations_allowed() ) { 269 $message = __( 'Member registration is allowed by invitation only.', 'buddypress' ); 270 // Is the user trying to accept an invitation but something is wrong? 271 if ( ! empty( $_GET['inv'] ) ) { 272 $message .= __( ' It looks like there is a problem with your invitation. Please try again.', 'buddypress' ); 273 } 274 } 275 return $message; 276 } -
src/bp-members/bp-members-functions.php
diff --git src/bp-members/bp-members-functions.php src/bp-members/bp-members-functions.php index 925759030..8f7f5c55b 100644
function bp_members_avatar_upload_dir( $directory = 'avatars', $user_id = 0 ) { 3046 3046 'error' => false 3047 3047 ) ); 3048 3048 } 3049 3050 /** 3051 * Get invitations to the BP community filtered by arguments. 3052 * 3053 * @since 7.0.0 3054 * 3055 * @param array $args Invitation arguments. 3056 * See BP_Invitation::get() for list. 3057 * 3058 * @return array $invites Matching BP_Invitation objects. 3059 */ 3060 function bp_members_invitations_get_invites( $args = array() ) { 3061 $invites_class = new BP_Members_Invitation_Manager(); 3062 return $invites_class->get_invitations( $args ); 3063 } 3064 3065 /** 3066 * Invite a user to a BP community. 3067 * 3068 * @since 7.0.0 3069 * 3070 * @param array|string $args { 3071 * Array of arguments. 3072 * @type int $invitee_email Email address of the user being invited. 3073 * @type int $network_id ID of the network to which the user is being invited. 3074 * @type int $inviter_id Optional. ID of the inviting user. Default: 3075 * ID of the logged-in user. 3076 * @type string $date_modified Optional. Modified date for the invitation. 3077 * Default: current date/time. 3078 * @type string $content Optional. Message to invitee. 3079 * @type bool $send_invite Optional. Whether the invitation should be 3080 * sent now. Default: false. 3081 * } 3082 * @return bool True on success, false on failure. 3083 */ 3084 function bp_members_invitations_invite_user( $args ) { 3085 $r = bp_parse_args( $args, array( 3086 'invitee_email' => '', 3087 'network_id' => get_current_network_id(), 3088 'inviter_id' => bp_loggedin_user_id(), 3089 'date_modified' => bp_core_current_time(), 3090 'content' => '', 3091 'send_invite' => 0 3092 ), 'community_invite_user' ); 3093 3094 $inv_args = array( 3095 'invitee_email' => $r['invitee_email'], 3096 'item_id' => $r['network_id'], 3097 'inviter_id' => $r['inviter_id'], 3098 'date_modified' => $r['date_modified'], 3099 'content' => $r['content'], 3100 'send_invite' => $r['send_invite'] 3101 ); 3102 3103 // Create the invitataion. 3104 $invites_class = new BP_Members_Invitation_Manager(); 3105 $created = $invites_class->add_invitation( $inv_args ); 3106 3107 /** 3108 * Fires after the creation of a new network invite. 3109 * 3110 * @since 7.0.0 3111 * 3112 * @param array $r Array of parsed arguments for the network invite. 3113 * @param int|bool $created The ID of the invitation or false if it couldn't be created. 3114 */ 3115 do_action( 'bp_members_invitations_invite_user', $r, $created ); 3116 3117 return $created; 3118 } 3119 3120 /** 3121 * Resend a community invitation email by id. 3122 * 3123 * @since 7.0.0 3124 * 3125 * @param int $id ID of the invitation to resend. 3126 * @return bool True on success, false on failure. 3127 */ 3128 function bp_members_invitation_resend_by_id( $id = 0 ) { 3129 3130 // Find the invitation before deleting it. 3131 $existing_invite = new BP_Invitation( $id ); 3132 $invites_class = new BP_Members_Invitation_Manager(); 3133 $success = $invites_class->send_invitation_by_id( $id ); 3134 3135 if ( ! $success ) { 3136 return $success; 3137 } 3138 3139 /** 3140 * Fires after the re-sending of a network invite. 3141 * 3142 * @since 7.0.0 3143 * 3144 * @param BP_Invitation $existing_invite The invitation that was resent. 3145 */ 3146 do_action( 'bp_members_invitations_resend_invitation', $existing_invite ); 3147 3148 return $success; 3149 } 3150 3151 /** 3152 * Delete a community invitation by id. 3153 * 3154 * @since 7.0.0 3155 * 3156 * @param int $id ID of the invitation to delete. 3157 * @return int|bool Number of rows deleted on success, false on failure. 3158 */ 3159 function bp_members_invitations_delete_by_id( $id = 0 ) { 3160 3161 // Find the invitation before deleting it. 3162 $existing_invite = new BP_Invitation( $id ); 3163 $invites_class = new BP_Members_Invitation_Manager(); 3164 $success = $invites_class->delete_by_id( $id ); 3165 3166 if ( ! $success ) { 3167 return $success; 3168 } 3169 3170 // Run a different action depending on the status of the invite. 3171 if ( ! $existing_invite->invite_sent ) { 3172 /** 3173 * Fires after the deletion of an unsent community invite. 3174 * 3175 * @since 7.0.0 3176 * 3177 * @param BP_Invitation $existing_invite The invitation to be deleted. 3178 */ 3179 do_action( 'bp_members_invitations_canceled_invitation', $existing_invite ); 3180 } else if ( ! $existing_invite->accepted ) { 3181 /** 3182 * Fires after the deletion of a sent, but not yet accepted, community invite. 3183 * 3184 * @since 7.0.0 3185 * 3186 * @param BP_Invitation $existing_invite The invitation to be deleted. 3187 */ 3188 do_action( 'bp_members_invitations_revoked_invitation', $existing_invite ); 3189 } else { 3190 /** 3191 * Fires after the deletion of a sent and accepted community invite. 3192 * 3193 * @since 7.0.0 3194 * 3195 * @param BP_Invitation $existing_invite The invitation to be deleted. 3196 */ 3197 do_action( 'bp_members_invitations_deleted_invitation', $existing_invite ); 3198 } 3199 3200 return $success; 3201 } 3202 3203 /** 3204 * Delete a network invitation. 3205 * 3206 * @since 7.0.0 3207 * 3208 * @param intring $args { 3209 * Array of arguments. 3210 * @type int|array $id Id(s) of the invitation(s) to remove. 3211 * @type int $invitee_email Email address of the user being invited. 3212 * @type int $network_id ID of the network to which the user is being invited. 3213 * @type int $inviter_id ID of the inviting user. 3214 * @type int $accepted Whether the invitation has been accepted yet. 3215 * @type int $invite_sent Whether the invitation has been sent yet. 3216 * } 3217 * @return bool True if all were deleted. 3218 */ 3219 function bp_members_invitations_delete_invites( $args ) { 3220 $r = bp_parse_args( $args, array( 3221 'id' => 0, 3222 'invitee_email' => '', 3223 'network_id' => get_current_network_id(), 3224 'inviter_id' => null, 3225 'accepted' => null, 3226 'invite_sent' => null 3227 ), 'community_invitation_delete_invites' ); 3228 3229 $inv_args = array( 3230 'id' => $r['id'], 3231 'invitee_email' => $r['invitee_email'], 3232 'item_id' => $r['network_id'], 3233 'inviter_id' => $r['inviter_id'], 3234 ); 3235 3236 // Find the invitation(s). 3237 $invites_class = new BP_Members_Invitation_Manager(); 3238 $invites = $invites_class->get_invitations( $inv_args ); 3239 $total_count = count( $invites ); 3240 3241 // Loop through, deleting each invitation. 3242 $deleted = 0; 3243 foreach ( $invites as $invite ) { 3244 $success = bp_members_invitations_delete_by_id( $invite->id ); 3245 if ( $success ) { 3246 $deleted++; 3247 } 3248 } 3249 3250 return $deleted === $total_count; 3251 } 3252 3253 /** 3254 * Get hash based on details of a community invitation and the inviter. 3255 * 3256 * @since 7.0.0 3257 * 3258 * @param BP_Invitation object $invitation Invitation to create hash from. 3259 * 3260 * @return string $hash Calculated sha1 hash. 3261 */ 3262 function bp_members_invitations_get_hash( BP_Invitation $invitation ) { 3263 $hash = false; 3264 3265 if ( ! empty( $invitation->id ) ) { 3266 $inviter_ud = get_userdata( $invitation->inviter_id ); 3267 if ( $inviter_ud ) { 3268 /* 3269 * Use some inviter details as part of the salt so that invitations from 3270 * users who are subsequently marked as spam will be invalidated. 3271 */ 3272 $hash = wp_hash( "{$invitation->inviter_id}:{$invitation->date_modified}", "{$inviter_ud->user_status}:{$inviter_ud->user_registered}" ); 3273 } 3274 } 3275 3276 // If there's a problem, return a string that will change and thus fail. 3277 if ( ! $hash ) { 3278 $hash = wp_generate_password( 32, false ); 3279 } 3280 3281 /** 3282 * Filters the hash calculated by the invitation details. 3283 * 3284 * @since 7.0.0 3285 * 3286 * @param string $hash Calculated sha1 hash. 3287 * @param BP_Invitation object $invitation Invitation hash was created from. 3288 */ 3289 return apply_filters( 'bp_members_invitations_get_hash', $hash, $invitation ); 3290 } 3291 3292 /** 3293 * Get the current invitation specified by the $_GET parameters. 3294 * 3295 * @since 7.0.0 3296 * 3297 * @return BP_Invitation $invite Invitation specified by the $_GET parameters. 3298 */ 3299 function bp_get_members_invitation_from_request() { 3300 $invites_class = new BP_Members_Invitation_Manager(); 3301 $invite = $invites_class->get_by_id( 0 ); 3302 3303 if ( bp_get_members_invitations_allowed() && ! empty( $_GET['inv'] ) ) { 3304 // Check to make sure the passed hash matches a calculated hash. 3305 $maybe_invite = $invites_class->get_by_id( absint( $_GET['inv'] ) ); 3306 $hash = bp_members_invitations_get_hash( $maybe_invite ); 3307 if ( $_GET['ih'] === $hash ) { 3308 $invite = $maybe_invite; 3309 } 3310 } 3311 3312 /** 3313 * Filters the invitation specified by the $_GET parameters. 3314 * 3315 * @since 7.0.0 3316 * 3317 * @param BP_Invitation $invite Invitation specified by the $_GET parameters. 3318 */ 3319 return apply_filters( 'bp_get_members_invitation_from_request', $invite ); 3320 } -
new file src/bp-members/bp-members-invitations.php
diff --git src/bp-members/bp-members-invitations.php src/bp-members/bp-members-invitations.php new file mode 100644 index 000000000..a91d82377
- + 1 <?php 2 /** 3 * BuddyPress Member Activity 4 * 5 * @package BuddyPress 6 * @subpackage MembersActivity 7 * @since 2.2.0 8 */ 9 10 // Exit if accessed directly. 11 defined( 'ABSPATH' ) || exit; 12 13 function bp_members_invitations_setup_nav() { 14 if ( ! bp_get_members_invitations_allowed() ) { 15 return; 16 } 17 18 $user_has_access = bp_user_has_access() && bp_user_can( bp_displayed_user_id(), 'bp_members_send_invitation' ); 19 20 /* Add 'Invitations' to the main user profile navigation */ 21 bp_core_new_nav_item( 22 array( 23 'name' => __( 'Invitations', 'buddypress' ), 24 'slug' => bp_get_members_invitations_slug(), 25 'position' => 80, 26 'screen_function' => 'members_screen_send_invites', 27 'default_subnav_slug' => 'list-invites', 28 'show_for_displayed_user' => $user_has_access 29 ) 30 ); 31 32 $parent_link = trailingslashit( bp_displayed_user_domain() . bp_get_members_invitations_slug() ); 33 34 /* Create two subnav items for community invitations */ 35 bp_core_new_subnav_item( 36 array( 37 'name' => __( 'Sent Invites', 'buddypress' ), 38 'slug' => 'list-invites', 39 'parent_slug' => bp_get_members_invitations_slug(), 40 'parent_url' => $parent_link, 41 'screen_function' => 'members_screen_list_sent_invites', 42 'position' => 10, 43 'user_has_access' => $user_has_access 44 ) 45 ); 46 47 bp_core_new_subnav_item( 48 array( 49 'name' => __( 'Invite New Members', 'buddypress' ), 50 'slug' => 'send-invites', 51 'parent_slug' => bp_get_members_invitations_slug(), 52 'parent_url' => $parent_link, 53 'screen_function' => 'members_screen_send_invites', 54 'position' => 20, 55 'user_has_access' => $user_has_access && bp_is_my_profile() 56 ) 57 ); 58 } 59 add_action( 'bp_setup_nav', 'bp_members_invitations_setup_nav' ); 60 61 /** 62 * When a user joins the network via an invitation, skip sending the activation email. 63 * 64 * @param bool $send Whether or not to send the activation key. 65 * @param int $user_id User ID to send activation key to. 66 * @param string $user_email User email to send activation key to. 67 * @param string $activation_key Activation key to be sent. 68 * @param array $usermeta Miscellaneous metadata about the user (blog-specific 69 * signup data, xprofile data, etc). 70 */ 71 function bp_members_invitations_cancel_activation_email( $send, $user_id, $user_email, $activation_key, $usermeta ) { 72 73 $invite = bp_members_invitations_get_invites( 74 array( 75 'invitee_email' => $user_email, 76 'invite_sent' => 'sent' 77 ) 78 ); 79 80 if ( $invite ) { 81 $send = false; 82 } 83 84 return $send; 85 } 86 add_filter( 'bp_core_signup_send_activation_key', 'bp_members_invitations_cancel_activation_email', 10, 5 ); 87 88 89 /** 90 * When a user joins the network via an invitation: 91 * - mark all invitations and requests as accepted 92 * - activate the user upon signup 93 * 94 * @param bool|WP_Error $user_id True on success, WP_Error on failure. 95 * @param string $user_login Login name requested by the user. 96 * @param string $user_password Password requested by the user. 97 * @param string $user_email Email address requested by the user. 98 */ 99 function bp_members_invitations_complete_signup( $user_id, $user_login, $user_password, $user_email ) { 100 if ( ! $user_id ) { 101 return; 102 } 103 104 // Is this new signup the result of an invitation? 105 $invite = bp_members_invitations_get_invites( 106 array( 107 'invitee_email' => $user_email, 108 'invite_sent' => 'sent' 109 ) 110 ); 111 112 113 if ( ! $invite ) { 114 return; 115 } 116 117 $invites_class = new BP_Members_Invitation_Manager(); 118 $args = array( 119 'invitee_email' => $user_email, 120 'item_id' => get_current_network_id(), 121 'type' => 'all' 122 ); 123 $invites_class->mark_accepted( $args ); 124 125 // User has already verified their email by responding to the invitation, so we can activate. 126 $key = bp_get_user_meta( $user_id, 'activation_key', true ); 127 if ( $key ) { 128 /** 129 * Filters the activation signup. 130 * 131 * @since 1.1.0 132 * 133 * @param bool|int $value Value returned by activation. 134 * Integer on success, boolean on failure. 135 */ 136 $user = apply_filters( 'bp_core_activate_account', bp_core_activate_signup( $key ) ); 137 138 // If there were errors, add a message and redirect. 139 if ( ! empty( $user->errors ) ) { 140 bp_core_add_message( $user->get_error_message(), 'error' ); 141 bp_core_redirect( trailingslashit( bp_get_root_domain() . '/' . $bp->pages->activate->slug ) ); 142 } 143 144 bp_core_add_message( __( 'Your account is now active!', 'buddypress' ) ); 145 bp_core_redirect( add_query_arg( 'activated', '1', bp_get_activation_page() ) ); 146 } 147 } 148 add_action( 'bp_core_signup_user', 'bp_members_invitations_complete_signup', 10, 4 ); 149 No newline at end of file -
new file src/bp-members/bp-members-notifications.php
diff --git src/bp-members/bp-members-notifications.php src/bp-members/bp-members-notifications.php new file mode 100644 index 000000000..c544e87d8
- + 1 <?php 2 /** 3 * BuddyPress Members Notification Functions. 4 * 5 * These functions handle the recording, deleting and formatting of notifications 6 * for the user and for this specific component. 7 * 8 * @package BuddyPress 9 * @subpackage Members 10 * @since 1.0.0 11 */ 12 13 // Exit if accessed directly. 14 defined( 'ABSPATH' ) || exit; 15 16 /** Emails ********************************************************************/ 17 18 /** 19 * Notify site admins about new membership request. 20 * 21 * @since 1.0.0 22 * 23 * @param int $requesting_user_id ID of the user requesting site membership. 24 * @param int $admin_id ID of the site admin. 25 * @param int $invitation_id ID of the network invitation object. 26 */ 27 function bp_members_new_membership_request( $requesting_user_id = 0, $admin_id = 0, $membership_id = 0 ) { 28 29 // @TODO 30 return; 31 32 // Trigger a BuddyPress Notification. 33 if ( bp_is_active( 'notifications' ) ) { 34 bp_notifications_add_notification( array( 35 'user_id' => $admin_id, 36 'item_id' => $group_id, 37 'secondary_item_id' => $requesting_user_id, 38 'component_name' => buddypress()->members->id, 39 'component_action' => 'new_membership_request', 40 ) ); 41 } 42 43 // Bail if member opted out of receiving this email. 44 if ( 'no' === bp_get_user_meta( $admin_id, 'notification_members_membership_request', true ) ) { 45 return; 46 } 47 48 $unsubscribe_args = array( 49 'user_id' => $admin_id, 50 'notification_type' => 'members-membership-request', 51 ); 52 53 $request_message = ''; 54 $requests = groups_get_requests( $args = array( 55 'user_id' => $requesting_user_id, 56 'item_id' => $group_id, 57 ) ); 58 if ( $requests ) { 59 $request_message = current( $requests )->content; 60 } 61 62 $group = groups_get_group( $group_id ); 63 $args = array( 64 'tokens' => array( 65 'admin.id' => $admin_id, 66 'group' => $group, 67 'group.name' => $group->name, 68 'group.id' => $group_id, 69 'group-requests.url' => esc_url( bp_get_group_permalink( $group ) . 'admin/membership-requests' ), 70 'profile.url' => esc_url( bp_core_get_user_domain( $requesting_user_id ) ), 71 'requesting-user.id' => $requesting_user_id, 72 'requesting-user.name' => bp_core_get_user_displayname( $requesting_user_id ), 73 'request.message' => $request_message, 74 'unsubscribe' => esc_url( bp_email_get_unsubscribe_link( $unsubscribe_args ) ), 75 ), 76 ); 77 bp_send_email( 'network-membership-request', (int) $admin_id, $args ); 78 } 79 80 /** 81 * Notify member about their group membership request. 82 * 83 * @since 1.0.0 84 * 85 * @param int $requesting_user_id ID of the user requesting group membership. 86 * @param int $group_id ID of the group. 87 * @param bool $accepted Optional. Whether the membership request was accepted. 88 * Default: true. 89 */ 90 function bp_members_membership_request_completed( $requesting_user_id = 0, $group_id = 0, $accepted = true ) { 91 92 // @TODO 93 return; 94 95 // Trigger a BuddyPress Notification. 96 if ( bp_is_active( 'notifications' ) ) { 97 98 // What type of acknowledgement. 99 $type = ! empty( $accepted ) ? 'membership_request_accepted' : 'membership_request_rejected'; 100 101 bp_notifications_add_notification( array( 102 'user_id' => $requesting_user_id, 103 'item_id' => $group_id, 104 'component_name' => buddypress()->groups->id, 105 'component_action' => $type, 106 ) ); 107 } 108 109 // Bail if member opted out of receiving this email. 110 if ( 'no' === bp_get_user_meta( $requesting_user_id, 'notification_membership_request_completed', true ) ) { 111 return; 112 } 113 114 $group = groups_get_group( $group_id ); 115 $args = array( 116 'tokens' => array( 117 'group' => $group, 118 'group.id' => $group_id, 119 'group.name' => $group->name, 120 'group.url' => esc_url( bp_get_group_permalink( $group ) ), 121 'requesting-user.id' => $requesting_user_id, 122 ), 123 ); 124 125 if ( ! empty( $accepted ) ) { 126 127 $unsubscribe_args = array( 128 'user_id' => $requesting_user_id, 129 'notification_type' => 'groups-membership-request-accepted', 130 ); 131 132 $args['tokens']['unsubscribe'] = esc_url( bp_email_get_unsubscribe_link( $unsubscribe_args ) ); 133 134 bp_send_email( 'groups-membership-request-accepted', (int) $requesting_user_id, $args ); 135 136 } else { 137 138 $unsubscribe_args = array( 139 'user_id' => $requesting_user_id, 140 'notification_type' => 'groups-membership-request-rejected', 141 ); 142 143 $args['tokens']['unsubscribe'] = esc_url( bp_email_get_unsubscribe_link( $unsubscribe_args ) ); 144 145 bp_send_email( 'groups-membership-request-rejected', (int) $requesting_user_id, $args ); 146 } 147 } 148 // @TODO 149 // add_action( 'groups_membership_accepted', 'groups_notification_membership_request_completed', 10, 3 ); 150 // add_action( 'groups_membership_rejected', 'groups_notification_membership_request_completed', 10, 3 ); 151 152 /** Notifications *************************************************************/ 153 154 /** 155 * Format notifications for the Groups component. 156 * 157 * @since 1.0.0 158 * 159 * @param string $action The kind of notification being rendered. 160 * @param int $item_id The primary item ID. 161 * @param int $secondary_item_id The secondary item ID. 162 * @param int $total_items The total number of messaging-related notifications 163 * waiting for the user. 164 * @param string $format 'string' for BuddyBar-compatible notifications; 'array' 165 * for WP Toolbar. Default: 'string'. 166 * @return string 167 */ 168 function bp_members_format_notifications( $action, $item_id, $secondary_item_id, $total_items, $format = 'string' ) { 169 170 // @TODO 171 switch ( $action ) { 172 case 'new_membership_request': 173 $group_id = $item_id; 174 $requesting_user_id = $secondary_item_id; 175 176 $group = groups_get_group( $group_id ); 177 $group_link = bp_get_group_permalink( $group ); 178 $amount = 'single'; 179 180 // Set up the string and the filter 181 // because different values are passed to the filters, 182 // we'll return values inline. 183 if ( (int) $total_items > 1 ) { 184 $text = sprintf( __( '%1$d new membership requests for the group "%2$s"', 'buddypress' ), (int) $total_items, $group->name ); 185 $amount = 'multiple'; 186 $notification_link = $group_link . 'admin/membership-requests/?n=1'; 187 188 if ( 'string' == $format ) { 189 190 /** 191 * Filters groups multiple new membership request notification for string format. 192 * 193 * This is a dynamic filter that is dependent on item count and action. 194 * Complete filter - bp_groups_multiple_new_membership_requests_notification. 195 * 196 * @since 1.0.0 197 * 198 * @param string $string HTML anchor tag for request. 199 * @param string $group_link The permalink for the group. 200 * @param int $total_items Total number of membership requests. 201 * @param string $group->name Name of the group. 202 * @param string $text Notification content. 203 * @param string $notification_link The permalink for notification. 204 */ 205 return apply_filters( 'bp_groups_' . $amount . '_' . $action . 's_notification', '<a href="' . $notification_link . '">' . $text . '</a>', $group_link, $total_items, $group->name, $text, $notification_link ); 206 } else { 207 208 /** 209 * Filters groups multiple new membership request notification for any non-string format. 210 * 211 * This is a dynamic filter that is dependent on item count and action. 212 * Complete filter - bp_groups_multiple_new_membership_requests_notification. 213 * 214 * @since 1.0.0 215 * 216 * @param array $array Array holding permalink and content for notification. 217 * @param string $group_link The permalink for the group. 218 * @param int $total_items Total number of membership requests. 219 * @param string $group->name Name of the group. 220 * @param string $text Notification content. 221 * @param string $notification_link The permalink for notification. 222 */ 223 return apply_filters( 'bp_groups_' . $amount . '_' . $action . 's_notification', array( 224 'link' => $notification_link, 225 'text' => $text 226 ), $group_link, $total_items, $group->name, $text, $notification_link ); 227 } 228 } else { 229 $user_fullname = bp_core_get_user_displayname( $requesting_user_id ); 230 $text = sprintf( __( '%s requests group membership', 'buddypress' ), $user_fullname ); 231 $notification_link = $group_link . 'admin/membership-requests/?n=1'; 232 233 if ( 'string' == $format ) { 234 235 /** 236 * Filters groups single new membership request notification for string format. 237 * 238 * This is a dynamic filter that is dependent on item count and action. 239 * Complete filter - bp_groups_single_new_membership_request_notification. 240 * 241 * @since 1.0.0 242 * 243 * @param string $string HTML anchor tag for request. 244 * @param string $group_link The permalink for the group. 245 * @param string $user_fullname Full name of requesting user. 246 * @param string $group->name Name of the group. 247 * @param string $text Notification content. 248 * @param string $notification_link The permalink for notification. 249 */ 250 return apply_filters( 'bp_groups_' . $amount . '_' . $action . '_notification', '<a href="' . $notification_link . '">' . $text . '</a>', $group_link, $user_fullname, $group->name, $text, $notification_link ); 251 } else { 252 253 /** 254 * Filters groups single new membership request notification for any non-string format. 255 * 256 * This is a dynamic filter that is dependent on item count and action. 257 * Complete filter - bp_groups_single_new_membership_request_notification. 258 * 259 * @since 1.0.0 260 * 261 * @param array $array Array holding permalink and content for notification. 262 * @param string $group_link The permalink for the group. 263 * @param string $user_fullname Full name of requesting user. 264 * @param string $group->name Name of the group. 265 * @param string $text Notification content. 266 * @param string $notification_link The permalink for notification. 267 */ 268 return apply_filters( 'bp_groups_' . $amount . '_' . $action . '_notification', array( 269 'link' => $notification_link, 270 'text' => $text 271 ), $group_link, $user_fullname, $group->name, $text, $notification_link ); 272 } 273 } 274 275 break; 276 277 case 'membership_request_accepted': 278 $group_id = $item_id; 279 280 $group = groups_get_group( $group_id ); 281 $group_link = bp_get_group_permalink( $group ); 282 $amount = 'single'; 283 284 if ( (int) $total_items > 1 ) { 285 $text = sprintf( __( '%d accepted group membership requests', 'buddypress' ), (int) $total_items, $group->name ); 286 $amount = 'multiple'; 287 $notification_link = trailingslashit( bp_loggedin_user_domain() . bp_get_groups_slug() ) . '?n=1'; 288 289 if ( 'string' == $format ) { 290 291 /** 292 * Filters multiple accepted group membership requests notification for string format. 293 * Complete filter - bp_groups_multiple_membership_request_accepted_notification. 294 * 295 * @since 1.0.0 296 * 297 * @param string $string HTML anchor tag for notification. 298 * @param int $total_items Total number of accepted requests. 299 * @param string $group->name Name of the group. 300 * @param string $text Notification content. 301 * @param string $notification_link The permalink for notification. 302 */ 303 return apply_filters( 'bp_groups_' . $amount . '_' . $action . '_notification', '<a href="' . $notification_link . '">' . $text . '</a>', $total_items, $group->name, $text, $notification_link ); 304 } else { 305 306 /** 307 * Filters multiple accepted group membership requests notification for non-string format. 308 * Complete filter - bp_groups_multiple_membership_request_accepted_notification. 309 * 310 * @since 1.0.0 311 * 312 * @param array $array Array holding permalink and content for notification 313 * @param int $total_items Total number of accepted requests. 314 * @param string $group->name Name of the group. 315 * @param string $text Notification content. 316 * @param string $notification_link The permalink for notification. 317 */ 318 return apply_filters( 'bp_groups_' . $amount . '_' . $action . '_notification', array( 319 'link' => $notification_link, 320 'text' => $text 321 ), $total_items, $group->name, $text, $notification_link ); 322 } 323 } else { 324 $text = sprintf( __( 'Membership for group "%s" accepted', 'buddypress' ), $group->name ); 325 $filter = 'bp_groups_single_membership_request_accepted_notification'; 326 $notification_link = $group_link . '?n=1'; 327 328 if ( 'string' == $format ) { 329 330 /** 331 * Filters single accepted group membership request notification for string format. 332 * Complete filter - bp_groups_single_membership_request_accepted_notification. 333 * 334 * @since 1.0.0 335 * 336 * @param string $string HTML anchor tag for notification. 337 * @param string $group_link The permalink for the group. 338 * @param string $group->name Name of the group. 339 * @param string $text Notification content. 340 * @param string $notification_link The permalink for notification. 341 */ 342 return apply_filters( 'bp_groups_' . $amount . '_' . $action . '_notification', '<a href="' . $notification_link . '">' . $text . '</a>', $group_link, $group->name, $text, $notification_link ); 343 } else { 344 345 /** 346 * Filters single accepted group membership request notification for non-string format. 347 * Complete filter - bp_groups_single_membership_request_accepted_notification. 348 * 349 * @since 1.0.0 350 * 351 * @param array $array Array holding permalink and content for notification. 352 * @param string $group_link The permalink for the group. 353 * @param string $group->name Name of the group. 354 * @param string $text Notification content. 355 * @param string $notification_link The permalink for notification. 356 */ 357 return apply_filters( $filter, array( 358 'link' => $notification_link, 359 'text' => $text 360 ), $group_link, $group->name, $text, $notification_link ); 361 } 362 } 363 364 break; 365 366 case 'membership_request_rejected': 367 $group_id = $item_id; 368 369 $group = groups_get_group( $group_id ); 370 $group_link = bp_get_group_permalink( $group ); 371 $amount = 'single'; 372 373 if ( (int) $total_items > 1 ) { 374 $text = sprintf( __( '%d rejected group membership requests', 'buddypress' ), (int) $total_items, $group->name ); 375 $amount = 'multiple'; 376 $notification_link = trailingslashit( bp_loggedin_user_domain() . bp_get_groups_slug() ) . '?n=1'; 377 378 if ( 'string' == $format ) { 379 380 /** 381 * Filters multiple rejected group membership requests notification for string format. 382 * Complete filter - bp_groups_multiple_membership_request_rejected_notification. 383 * 384 * @since 1.0.0 385 * 386 * @param string $string HTML anchor tag for notification. 387 * @param int $total_items Total number of rejected requests. 388 * @param string $group->name Name of the group. 389 * @param string $text Notification content. 390 * @param string $notification_link The permalink for notification. 391 */ 392 return apply_filters( 'bp_groups_' . $amount . '_' . $action . '_notification', '<a href="' . $notification_link . '">' . $text . '</a>', $total_items, $group->name ); 393 } else { 394 395 /** 396 * Filters multiple rejected group membership requests notification for non-string format. 397 * Complete filter - bp_groups_multiple_membership_request_rejected_notification. 398 * 399 * @since 1.0.0 400 * 401 * @param array $array Array holding permalink and content for notification. 402 * @param int $total_items Total number of rejected requests. 403 * @param string $group->name Name of the group. 404 * @param string $text Notification content. 405 * @param string $notification_link The permalink for notification. 406 */ 407 return apply_filters( 'bp_groups_' . $amount . '_' . $action . '_notification', array( 408 'link' => $notification_link, 409 'text' => $text 410 ), $total_items, $group->name, $text, $notification_link ); 411 } 412 } else { 413 $text = sprintf( __( 'Membership for group "%s" rejected', 'buddypress' ), $group->name ); 414 $notification_link = $group_link . '?n=1'; 415 416 if ( 'string' == $format ) { 417 418 /** 419 * Filters single rejected group membership requests notification for string format. 420 * Complete filter - bp_groups_single_membership_request_rejected_notification. 421 * 422 * @since 1.0.0 423 * 424 * @param string $string HTML anchor tag for notification. 425 * @param int $group_link The permalink for the group. 426 * @param string $group->name Name of the group. 427 * @param string $text Notification content. 428 * @param string $notification_link The permalink for notification. 429 */ 430 return apply_filters( 'bp_groups_' . $amount . '_' . $action . '_notification', '<a href="' . $notification_link . '">' . $text . '</a>', $group_link, $group->name, $text, $notification_link ); 431 } else { 432 433 /** 434 * Filters single rejected group membership requests notification for non-string format. 435 * Complete filter - bp_groups_single_membership_request_rejected_notification. 436 * 437 * @since 1.0.0 438 * 439 * @param array $array Array holding permalink and content for notification. 440 * @param int $group_link The permalink for the group. 441 * @param string $group->name Name of the group. 442 * @param string $text Notification content. 443 * @param string $notification_link The permalink for notification. 444 */ 445 return apply_filters( 'bp_groups_' . $amount . '_' . $action . '_notification', array( 446 'link' => $notification_link, 447 'text' => $text 448 ), $group_link, $group->name, $text, $notification_link ); 449 } 450 } 451 452 break; 453 454 default: 455 456 /** 457 * Filters plugin-added group-related custom component_actions. 458 * 459 * @since 2.4.0 460 * 461 * @param string $notification Null value. 462 * @param int $item_id The primary item ID. 463 * @param int $secondary_item_id The secondary item ID. 464 * @param int $total_items The total number of messaging-related notifications 465 * waiting for the user. 466 * @param string $format 'string' for BuddyBar-compatible notifications; 467 * 'array' for WP Toolbar. 468 */ 469 $custom_action_notification = apply_filters( 'bp_members_' . $action . '_notification', null, $item_id, $secondary_item_id, $total_items, $format ); 470 471 if ( ! is_null( $custom_action_notification ) ) { 472 return $custom_action_notification; 473 } 474 475 break; 476 } 477 478 /** 479 * Fires right before returning the formatted group notifications. 480 * 481 * @since 1.0.0 482 * 483 * @param string $action The type of notification being rendered. 484 * @param int $item_id The primary item ID. 485 * @param int $secondary_item_id The secondary item ID. 486 * @param int $total_items Total amount of items to format. 487 */ 488 do_action( 'members_format_notifications', $action, $item_id, $secondary_item_id, $total_items ); 489 490 return false; 491 } 492 493 /** 494 * Mark notifications read when a member's group membership request is granted. 495 * 496 * @since 2.8.0 497 * 498 * @param int $user_id ID of the user. 499 * @param int $group_id ID of the group. 500 */ 501 function bp_members_accept_request_mark_notifications( $user_id, $group_id ) { 502 // @TODO 503 if ( bp_is_active( 'notifications' ) ) { 504 // First null parameter marks read for all admins. 505 bp_notifications_mark_notifications_by_item_id( null, $group_id, buddypress()->groups->id, 'new_membership_request', $user_id ); 506 } 507 } 508 // @TODO 509 // add_action( 'groups_membership_accepted', 'bp_groups_accept_request_mark_notifications', 10, 2 ); 510 // add_action( 'groups_membership_rejected', 'bp_groups_accept_request_mark_notifications', 10, 2 ); 511 512 /** 513 * Render the group settings fields on the Notification Settings page. 514 * 515 * @since 6.0.0 516 */ 517 function bp_members_screen_notification_settings() { 518 519 if ( ! bp_user_can( bp_displayed_user_id(), 'manage_network_membership_requests' ) ) { 520 return; 521 } 522 523 if ( ! $network_membership_request = bp_get_user_meta( bp_displayed_user_id(), 'notification_network_membership_request', true ) ) { 524 $network_membership_request = 'yes'; 525 } 526 527 ?> 528 529 <table class="notification-settings" id="bp-members-notification-settings"> 530 <thead> 531 <tr> 532 <th class="icon"></th> 533 <th class="title"><?php _ex( 'Members', 'Member component settings on notification settings page', 'buddypress' ) ?></th> 534 <th class="yes"><?php _e( 'Yes', 'buddypress' ) ?></th> 535 <th class="no"><?php _e( 'No', 'buddypress' )?></th> 536 </tr> 537 </thead> 538 539 <tbody> 540 <tr id="bp-members-notification-settings-invitation"> 541 <td></td> 542 <td><?php _ex( 'A user requests membership on this network', 'Member component settings on notification settings page','buddypress' ) ?></td> 543 <td class="yes"><input type="radio" name="notifications[notification_network_membership_request]" id="notification_network_membership_request-yes" value="yes" <?php checked( $network_membership_request, 'yes', true ) ?>/><label for="notification_network_membership_request-yes" class="bp-screen-reader-text"><?php 544 /* translators: accessibility text */ 545 _e( 'Yes, send email', 'buddypress' ); 546 ?></label></td> 547 <td class="no"><input type="radio" name="notifications[notification_network_membership_request]" id="notification_network_membership_request-no" value="no" <?php checked( $network_membership_request, 'no', true ) ?>/><label for="notification_network_membership_request-no" class="bp-screen-reader-text"><?php 548 /* translators: accessibility text */ 549 _e( 'No, do not send email', 'buddypress' ); 550 ?></label></td> 551 </tr> 552 553 <?php 554 555 /** 556 * Fires at the end of the available group settings fields on Notification Settings page. 557 * 558 * @since 6.0.0 559 */ 560 do_action( 'bp_members_screen_notification_settings' ); ?> 561 562 </tbody> 563 </table> 564 565 <?php 566 } 567 add_action( 'bp_notification_settings', 'bp_members_screen_notification_settings' ); -
src/bp-members/bp-members-template.php
diff --git src/bp-members/bp-members-template.php src/bp-members/bp-members-template.php index b6dac6b9e..a0bf4f5a2 100644
function bp_activate_slug() { 274 274 return apply_filters( 'bp_get_activate_slug', $slug ); 275 275 } 276 276 277 /** 278 * Output the members invitation pane slug. 279 * 280 * @since 7.0.0 281 * 282 */ 283 function bp_members_invitations_slug() { 284 echo bp_get_members_invitations_slug(); 285 } 286 /** 287 * Return the members invitations root slug. 288 * 289 * @since 7.0.0 290 * 291 * @return string 292 */ 293 function bp_get_members_invitations_slug() { 294 295 /** 296 * Filters the Members invitations pane root slug. 297 * 298 * @since 7.0.0 299 * 300 * @param string $slug Members invitations pane root slug. 301 */ 302 return apply_filters( 'bp_get_members_invitations_slug', _x( 'invitations', 'Member profile invitations pane URL base', 'buddypress' ) ); 303 } 304 277 305 /** 278 306 * Initialize the members loop. 279 307 * … … function bp_signup_email_value() { 2194 2222 */ 2195 2223 function bp_get_signup_email_value() { 2196 2224 $value = ''; 2197 if ( isset( $_POST['signup_email'] ) ) 2225 if ( isset( $_POST['signup_email'] ) ) { 2198 2226 $value = $_POST['signup_email']; 2227 } else if ( bp_get_members_invitations_allowed() ) { 2228 $invite = bp_get_members_invitation_from_request(); 2229 if ( $invite ) { 2230 $value = $invite->invitee_email; 2231 } 2232 } 2199 2233 2200 2234 /** 2201 2235 * Filters the email address submitted during signup. … … function bp_signup_allowed() { 2568 2602 return apply_filters( 'bp_get_signup_allowed', (bool) bp_get_option( 'users_can_register' ) ); 2569 2603 } 2570 2604 2605 /** 2606 * Are users allowed to invite users to join this site? 2607 * 2608 * @since 7.0.0 2609 * 2610 * @return bool 2611 */ 2612 function bp_get_members_invitations_allowed() { 2613 /** 2614 * Filters whether or not community invitations are allowed. 2615 * 2616 * @since 7.0.0 2617 * 2618 * @param bool $allowed Whether or not community invitations are allowed. 2619 */ 2620 return apply_filters( 'bp_get_members_invitations_allowed', bp_is_active( 'members', 'invitations' ) && (bool) bp_get_option( 'bp-enable-members-invitations' ) ); 2621 } 2622 2571 2623 /** 2572 2624 * Hook member activity feed to <head>. 2573 2625 * … … function bp_avatar_delete_link() { 2674 2726 */ 2675 2727 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' ) ); 2676 2728 } 2729 2730 2731 /** The Members Invitations Loop ******************************************************************/ 2732 2733 /** 2734 * Initialize the community invitations loop. 2735 * 2736 * Based on the $args passed, bp_has_invitations() populates 2737 * buddypress()->invitations->query_loop global, enabling the use of BP 2738 * templates and template functions to display a list of invitations. 2739 * 2740 * @since 7.0.0 2741 * 2742 * @param array|string $args { 2743 * Arguments for limiting the contents of the invitations loop. Can be 2744 * passed as an associative array, or as a URL query string. 2745 * 2746 * See {@link BP_Invitations_Invitation::get()} for detailed 2747 * information on the arguments. In addition, also supports: 2748 * 2749 * @type int $max Optional. Max items to display. Default: false. 2750 * @type string $page_arg URL argument to use for pagination. 2751 * Default: 'ipage'. 2752 * } 2753 * @return bool 2754 */ 2755 function bp_has_members_invitations( $args = '' ) { 2756 2757 // Get the user ID. 2758 if ( bp_displayed_user_id() ) { 2759 $user_id = bp_displayed_user_id(); 2760 } else { 2761 $user_id = bp_loggedin_user_id(); 2762 } 2763 2764 // Set the search terms (by default an empty string to get all notifications) 2765 $search_terms = ''; 2766 2767 if ( isset( $_REQUEST['s'] ) ) { 2768 $search_terms = stripslashes( $_REQUEST['s'] ); 2769 } 2770 2771 // Parse the args. 2772 $r = bp_parse_args( $args, array( 2773 'id' => false, 2774 'inviter_id' => $user_id, 2775 'invitee_email' => false, 2776 'item_id' => false, 2777 'type' => 'invite', 2778 'invite_sent' => 'all', 2779 'accepted' => 'pending', 2780 'search_terms' => $search_terms, 2781 'order_by' => 'date_modified', 2782 'sort_order' => 'DESC', 2783 'page' => 1, 2784 'per_page' => 25, 2785 'fields' => 'all', 2786 2787 // These are additional arguments that are not available in 2788 // BP_Invitations_Invitation::get(). 2789 'page_arg' => 'ipage', 2790 ), 'has_community_invitations' ); 2791 2792 // Get the notifications. 2793 $query_loop = new BP_Members_Invitations_Template( $r ); 2794 2795 // Setup the global query loop. 2796 buddypress()->members->invitations->query_loop = $query_loop; 2797 2798 /** 2799 * Filters whether or not the user has network invitations to display. 2800 * 2801 * @since 7.0.0 2802 * 2803 * @param bool $value Whether or not there are network invitations to display. 2804 * @param BP_Notifications_Template $query_loop BP_Members_Invitations_Template object instance. 2805 * @param array $r Array of arguments passed into the BP_Members_Invitations_Template class. 2806 */ 2807 return apply_filters( 'bp_has_members_invitations', $query_loop->has_invitations(), $query_loop, $r ); 2808 } 2809 2810 /** 2811 * Get the network invitations returned by the template loop. 2812 * 2813 * @since 7.0.0 2814 * 2815 * @return array List of network invitations. 2816 */ 2817 function bp_the_members_invitations() { 2818 return buddypress()->members->invitations->query_loop->invitations(); 2819 } 2820 2821 /** 2822 * Get the current network invitation object in the loop. 2823 * 2824 * @since 7.0.0 2825 * 2826 * @return object The current network invitation within the loop. 2827 */ 2828 function bp_the_members_invitation() { 2829 return buddypress()->members->invitations->query_loop->the_invitation(); 2830 } 2831 2832 /** 2833 * Output the pagination count for the current network invitations loop. 2834 * 2835 * @since 7.0.0 2836 */ 2837 function bp_members_invitations_pagination_count() { 2838 echo bp_get_members_invitations_pagination_count(); 2839 } 2840 /** 2841 * Return the pagination count for the current network invitation loop. 2842 * 2843 * @since 7.0.0 2844 * 2845 * @return string HTML for the pagination count. 2846 */ 2847 function bp_get_members_invitations_pagination_count() { 2848 $query_loop = buddypress()->members->invitations->query_loop; 2849 $start_num = intval( ( $query_loop->pag_page - 1 ) * $query_loop->pag_num ) + 1; 2850 $from_num = bp_core_number_format( $start_num ); 2851 $to_num = bp_core_number_format( ( $start_num + ( $query_loop->pag_num - 1 ) > $query_loop->total_invitation_count ) ? $query_loop->total_invitation_count : $start_num + ( $query_loop->pag_num - 1 ) ); 2852 $total = bp_core_number_format( $query_loop->total_invitation_count ); 2853 2854 if ( 1 == $query_loop->total_invitation_count ) { 2855 $pag = __( 'Viewing 1 invitation', 'buddypress' ); 2856 } else { 2857 /* translators: 1: notification from number. 2: notification to number. 3: total notifications. */ 2858 $pag = sprintf( _n( 'Viewing %1$s - %2$s of %3$s invitation', 'Viewing %1$s - %2$s of %3$s invitations', $query_loop->total_invitation_count, 'buddypress' ), $from_num, $to_num, $total ); 2859 } 2860 2861 /** 2862 * Filters the pagination count for the current network invitation loop. 2863 * 2864 * @since 1.9.0 2865 * 2866 * @param string $pag HTML for the pagination count. 2867 */ 2868 return apply_filters( 'bp_get_members_invitations_pagination_count', $pag ); 2869 } 2870 2871 /** 2872 * Output the pagination links for the current network invitation loop. 2873 * 2874 * @since 7.0.0 2875 */ 2876 function bp_members_invitations_pagination_links() { 2877 echo bp_get_members_invitations_pagination_links(); 2878 } 2879 /** 2880 * Return the pagination links for the current network invitations loop. 2881 * 2882 * @since 7.0.0 2883 * 2884 * @return string HTML for the pagination links. 2885 */ 2886 function bp_get_members_invitations_pagination_links() { 2887 2888 /** 2889 * Filters the pagination links for the current network invitations loop. 2890 * 2891 * @since 7.0.0 2892 * 2893 * @param string $pag_links HTML for the pagination links. 2894 */ 2895 return apply_filters( 'bp_get_members_invitations_pagination_links', buddypress()->members->invitations->query_loop->pag_links ); 2896 } 2897 2898 /** 2899 * Output the ID of the invitation currently being iterated on. 2900 * 2901 * @since 7.0.0 2902 */ 2903 function bp_the_members_invitation_property( $property ) { 2904 echo bp_get_the_members_invitation_property( $property ); 2905 } 2906 /** 2907 * Return the value for a property of the network invitation currently being iterated on. 2908 * 2909 * @since 7.0.0 2910 * 2911 * @return int ID of the current network invitation. 2912 */ 2913 function bp_get_the_members_invitation_property( $property = 'id' ) { 2914 2915 switch ( $property ) { 2916 case 'id': 2917 case 'user_id': 2918 case 'item_id': 2919 case 'secondary_item_id': 2920 case 'invite_sent': 2921 case 'accepted': 2922 $value = 0; 2923 break; 2924 case 'invitee_email': 2925 case 'type': 2926 case 'content': 2927 case 'date_modified': 2928 $value = ''; 2929 break; 2930 default: 2931 // A known property has not been specified. 2932 $property = null; 2933 $value = ''; 2934 break; 2935 } 2936 2937 if ( isset( buddypress()->members->invitations->query_loop->invitation->{$property} ) ) { 2938 $value = buddypress()->members->invitations->query_loop->invitation->{$property}; 2939 } 2940 2941 /** 2942 * Filters the property of the network invitation currently being iterated on. 2943 * 2944 * @since 7.0.0 2945 * 2946 * @param int|string $value Property value of the network invitation being iterated on. 2947 */ 2948 return apply_filters( 'bp_get_the_members_invitation_property_' . $property, $value ); 2949 } 2950 2951 /** 2952 * Output the action links for the current invitation. 2953 * 2954 * @since 7.0.0 2955 * 2956 * @param array|string $args Array of arguments. 2957 */ 2958 function bp_the_members_invitation_action_links( $args = '' ) { 2959 echo bp_get_the_members_invitation_action_links( $args ); 2960 } 2961 /** 2962 * Return the action links for the current invitation. 2963 * 2964 * @since 7.0.0 2965 * 2966 * @param array|string $args { 2967 * @type string $before HTML before the links. 2968 * @type string $after HTML after the links. 2969 * @type string $sep HTML between the links. 2970 * @type array $links Array of links to implode by 'sep'. 2971 * @type int $user_id User ID to fetch action links for. Defaults to displayed user ID. 2972 * } 2973 * @return string HTML links for actions to take on single notifications. 2974 */ 2975 function bp_get_the_members_invitation_action_links( $args = '' ) { 2976 // Set default user ID to use. 2977 $inviter_id = isset( $args['inviter_id'] ) ? $args['inviter_id'] : bp_displayed_user_id(); 2978 2979 // Parse. 2980 $r = wp_parse_args( $args, array( 2981 'before' => '', 2982 'after' => '', 2983 'sep' => ' | ', 2984 'links' => array( 2985 bp_get_the_members_invitation_resend_link( $inviter_id ), 2986 bp_get_the_members_invitation_delete_link( $inviter_id ) 2987 ) 2988 ) ); 2989 2990 // Build the links. 2991 $retval = $r['before'] . implode( $r['sep'], $r['links'] ) . $r['after']; 2992 2993 /** 2994 * Filters the action links for the current notification. 2995 * 2996 * @since 1.9.0 2997 * @since 2.6.0 Added the `$r` parameter. 2998 * 2999 * @param string $retval HTML links for actions to take on single notifications. 3000 * @param array $r Array of parsed arguments. 3001 */ 3002 return apply_filters( 'bp_get_the_members_invitation_action_links', $retval, $r ); 3003 } 3004 3005 /** 3006 * Output the resend link for the current invitation. 3007 * 3008 * @since 7.0.0 3009 * 3010 * @param int $user_id The user ID. 3011 */ 3012 function bp_the_members_invitations_resend_link( $user_id = 0 ) { 3013 echo bp_get_the_members_invitation_delete_link( $user_id ); 3014 } 3015 /** 3016 * Return the resend link for the current notification. 3017 * 3018 * @since 7.0.0 3019 * 3020 * @param int $user_id The user ID. 3021 * @return string 3022 */ 3023 function bp_get_the_members_invitation_resend_link( $user_id = 0 ) { 3024 // Set default user ID to use. 3025 $user_id = 0 === $user_id ? bp_displayed_user_id() : $user_id; 3026 3027 // Don't allow resending of accepted invitations. 3028 if ( bp_get_the_members_invitation_property( 'accepted' ) ) { 3029 return; 3030 } 3031 3032 $retval = sprintf( '<a href="%1$s" class="resend secondary confirm bp-tooltip">%2$s</a>', esc_url( bp_get_the_members_invitations_resend_url( $user_id ) ), __( 'Resend', 'buddypress' ) ); 3033 3034 /** 3035 * Filters the resend link for the current invitation. 3036 * 3037 * @since 7.0.0 3038 * 3039 * @param string $retval HTML for the delete link for the current notification. 3040 * @param int $user_id The user ID. 3041 */ 3042 return apply_filters( 'bp_get_the_members_invitation_resend_link', $retval, $user_id ); 3043 } 3044 3045 /** 3046 * Output the URL used for resending a single invitation. 3047 * 3048 * Since this function directly outputs a URL, it is escaped. 3049 * 3050 * @since 7.0.0 3051 * 3052 * @param int $user_id The user ID. 3053 */ 3054 function bp_the_members_invitations_resend_url( $user_id = 0 ) { 3055 echo esc_url( bp_get_the_members_invitations_resend_url( $user_id ) ); 3056 } 3057 /** 3058 * Return the URL used for resending a single invitation. 3059 * 3060 * @since 7.0.0 3061 * 3062 * @param int $user_id The user ID. 3063 * @return string 3064 */ 3065 function bp_get_the_members_invitations_resend_url( $user_id = 0 ) { 3066 // Set default user ID to use. 3067 $user_id = 0 === $user_id ? bp_displayed_user_id() : $user_id; 3068 $link = bp_get_members_invitations_list_invites_permalink( $user_id ); 3069 3070 // Get the ID. 3071 $id = bp_get_the_members_invitation_property( 'id' ); 3072 3073 // Get the args to add to the URL. 3074 $args = array( 3075 'action' => 'resend', 3076 'invitation_id' => $id 3077 ); 3078 3079 // Add the args. 3080 $url = add_query_arg( $args, $link ); 3081 3082 // Add the nonce. 3083 $url = wp_nonce_url( $url, 'bp_network_invitation_resend_' . $id ); 3084 3085 /** 3086 * Filters the URL used for resending a single invitation. 3087 * 3088 * @since 7.0.0 3089 * 3090 * @param string $url URL used for deleting a single invitation. 3091 * @param int $user_id The user ID. 3092 */ 3093 return apply_filters( 'bp_get_the_members_invitations_resend_url', $url, $user_id ); 3094 } 3095 3096 /** 3097 * Output the delete link for the current invitation. 3098 * 3099 * @since 7.0.0 3100 * 3101 * @param int $user_id The user ID. 3102 */ 3103 function bp_the_members_invitations_delete_link( $user_id = 0 ) { 3104 echo bp_get_the_members_invitation_delete_link( $user_id ); 3105 } 3106 /** 3107 * Return the delete link for the current invitation. 3108 * 3109 * @since 7.0.0 3110 * 3111 * @param int $user_id The user ID. 3112 * @return string 3113 */ 3114 function bp_get_the_members_invitation_delete_link( $user_id = 0 ) { 3115 // Set default user ID to use. 3116 $user_id = 0 === $user_id ? bp_displayed_user_id() : $user_id; 3117 3118 // Modify the message for accepted/not accepted invitatons. 3119 if ( bp_get_the_members_invitation_property( 'accepted' ) ) { 3120 $message = __( 'Delete', 'buddypress' ); 3121 } else { 3122 $message = __( 'Cancel', 'buddypress' ); 3123 } 3124 3125 $retval = sprintf( '<a href="%1$s" class="delete secondary confirm bp-tooltip">%2$s</a>', esc_url( bp_get_the_members_invitations_delete_url( $user_id ) ), $message ); 3126 3127 /** 3128 * Filters the delete link for the current invitation. 3129 * 3130 * @since 7.0.0 3131 * 3132 * @param string $retval HTML for the delete link for the current notification. 3133 * @param int $user_id The user ID. 3134 */ 3135 return apply_filters( 'bp_get_the_members_invitation_delete_link', $retval, $user_id ); 3136 } 3137 3138 /** 3139 * Output the URL used for deleting a single invitation. 3140 * 3141 * Since this function directly outputs a URL, it is escaped. 3142 * 3143 * @since 7.0.0 3144 * 3145 * @param int $user_id The user ID. 3146 */ 3147 function bp_the_members_invitations_delete_url( $user_id = 0 ) { 3148 echo esc_url( bp_get_the_members_invitations_delete_url( $user_id ) ); 3149 } 3150 /** 3151 * Return the URL used for deleting a single invitation. 3152 * 3153 * @since 7.0.0 3154 * 3155 * @param int $user_id The user ID. 3156 * @return string 3157 */ 3158 function bp_get_the_members_invitations_delete_url( $user_id = 0 ) { 3159 // Set default user ID to use. 3160 $user_id = 0 === $user_id ? bp_displayed_user_id() : $user_id; 3161 $link = bp_get_members_invitations_list_invites_permalink( $user_id ); 3162 3163 // Get the ID. 3164 $id = bp_get_the_members_invitation_property( 'id' ); 3165 3166 // Get the args to add to the URL. 3167 $args = array( 3168 'action' => 'cancel', 3169 'invitation_id' => $id 3170 ); 3171 3172 // Add the args. 3173 $url = add_query_arg( $args, $link ); 3174 3175 // Add the nonce. 3176 $url = wp_nonce_url( $url, 'bp_members_invitations_cancel_' . $id ); 3177 3178 /** 3179 * Filters the URL used for deleting a single invitation. 3180 * 3181 * @since 7.0.0 3182 * 3183 * @param string $url URL used for deleting a single invitation. 3184 * @param int $user_id The user ID. 3185 */ 3186 return apply_filters( 'bp_get_the_members_invitations_delete_url', $url, $user_id ); 3187 } 3188 3189 /** 3190 * Output the members invitations list permalink for a user. 3191 * 3192 * @since 7.0.0 3193 * 3194 * @param int $user_id The user ID. 3195 */ 3196 function bp_members_invitations_list_invites_permalink( $user_id = 0 ) { 3197 echo bp_get_members_invitations_list_invites_permalink( $user_id ); 3198 } 3199 /** 3200 * Return the members invitations list permalink for a user. 3201 * 3202 * @since 7.0.0 3203 * 3204 * @return string Members invitations list permalink for a user. 3205 */ 3206 function bp_get_members_invitations_list_invites_permalink( $user_id = 0 ) { 3207 if ( 0 === $user_id ) { 3208 $user_id = bp_loggedin_user_id(); 3209 $domain = bp_loggedin_user_domain(); 3210 } else { 3211 $domain = bp_core_get_user_domain( (int) $user_id ); 3212 } 3213 3214 $retval = trailingslashit( $domain . bp_get_members_invitations_slug() . '/list-invites' ); 3215 3216 /** 3217 * Filters the members invitations list permalink for a user. 3218 * 3219 * @since 7.0.0 3220 * 3221 * @param string $retval Permalink for the sent invitation list screen. 3222 * @param int $user_id The user ID. 3223 */ 3224 return apply_filters( 'bp_get_members_invitations_list_invites_permalink', $retval, $user_id ); 3225 } 3226 3227 /** 3228 * Output the send invitation permalink for a user. 3229 * 3230 * @since 7.0.0 3231 * 3232 * @param int $user_id The user ID. 3233 */ 3234 function bp_members_invitations_send_invites_permalink( $user_id = 0 ) { 3235 echo bp_get_members_invitations_send_invites_permalink( $user_id ); 3236 } 3237 /** 3238 * Return the send invitations permalink. 3239 * 3240 * @since 7.0.0 3241 * 3242 * @return string Read notifications permalink. 3243 */ 3244 function bp_get_members_invitations_send_invites_permalink( $user_id = 0 ) { 3245 if ( 0 === $user_id ) { 3246 $user_id = bp_loggedin_user_id(); 3247 $domain = bp_loggedin_user_domain(); 3248 } else { 3249 $domain = bp_core_get_user_domain( (int) $user_id ); 3250 } 3251 3252 $retval = trailingslashit( $domain . bp_get_members_invitations_slug() . '/send-invites' ); 3253 3254 /** 3255 * Filters the read notifications permalink. 3256 * 3257 * @since 7.0.0 3258 * 3259 * @param string $retval Permalink for the sent invitation list screen. 3260 * @param int $user_id The user ID. 3261 */ 3262 return apply_filters( 'bp_get_members_invitations_send_invites_permalink', $retval, $user_id ); 3263 } 3264 No newline at end of file -
src/bp-members/classes/class-bp-members-admin.php
diff --git src/bp-members/classes/class-bp-members-admin.php src/bp-members/classes/class-bp-members-admin.php index 4846b8837..6ea9b3a4a 100644
class BP_Members_Admin { 140 140 $this->users_url = bp_get_admin_url( 'users.php' ); 141 141 $this->users_screen = bp_core_do_network_admin() ? 'users-network' : 'users'; 142 142 143 $this->members_invites_page = ''; 144 143 145 // Specific config: BuddyPress is not network activated. 144 146 $this->subsite_activated = (bool) is_multisite() && ! bp_is_network_activated(); 145 147 … … class BP_Members_Admin { 248 250 * @param string $value 249 251 */ 250 252 public function multisite_registration_on( $option_name, $value ) { 251 if ( 'user' === $value || 'all' === $value ) { 253 // Is registration enabled or are network invitations enabled? 254 if ( ( 'user' === $value || 'all' === $value ) 255 || bp_get_members_invitations_allowed() ) { 252 256 bp_core_add_page_mappings( array( 253 257 'register' => 1, 254 258 'activate' => 1 … … class BP_Members_Admin { 266 270 */ 267 271 public function single_site_registration_on( $old_value, $value ) { 268 272 // Single site. 269 if ( ! is_multisite() && ! empty( $value) ) {273 if ( ! is_multisite() && ( ! empty( $value ) || bp_get_members_invitations_allowed() ) ) { 270 274 bp_core_add_page_mappings( array( 271 275 'register' => 1, 272 276 'activate' => 1 … … class BP_Members_Admin { 488 492 'bp-signups', 489 493 array( $this, 'signups_admin' ) 490 494 ); 495 496 // Manage invitations. 497 $hooks['members_invitations'] = $this->members_invites_page = add_users_page( 498 __( 'Manage Invitations', 'buddypress' ), 499 __( 'Manage Invitations', 'buddypress' ), 500 $this->capability, 501 'bp-members-invitations', 502 array( $this, 'invitations_admin' ) 503 ); 491 504 } 492 505 493 506 $edit_page = 'user-edit'; … … class BP_Members_Admin { 509 522 $this->user_page .= '-network'; 510 523 $this->users_page .= '-network'; 511 524 $this->signups_page .= '-network'; 525 526 $this->members_invites_page .= '-network'; 512 527 } 513 528 514 529 // Setup the screen ID's. … … class BP_Members_Admin { 2588 2603 2589 2604 return $value; 2590 2605 } 2606 2607 /** 2608 * Set up the signups admin page. 2609 * 2610 * Loaded before the page is rendered, this function does all initial 2611 * setup, including: processing form requests, registering contextual 2612 * help, and setting up screen options. 2613 * 2614 * @since 7.0.0 2615 * 2616 * @global $bp_members_signup_list_table 2617 */ 2618 public function members_invitations_admin_load() { 2619 // @TODO 2620 } 2621 2622 /** 2623 * Network invitations admin page router. 2624 * 2625 * Depending on the context, display 2626 * - the list of invitations, 2627 * - or the delete confirmation screen, 2628 * - or the activate confirmation screen, 2629 * - or the "resend" email confirmation screen. 2630 * 2631 * Also prepare the admin notices. 2632 * 2633 * @since 7.0.0 2634 */ 2635 public function invitations_admin() { 2636 // @TODO 2637 echo "<p>Coming Soon? :)</p>"; 2638 } 2591 2639 } 2592 2640 endif; // End class_exists check. -
src/bp-members/classes/class-bp-members-component.php
diff --git src/bp-members/classes/class-bp-members-component.php src/bp-members/classes/class-bp-members-component.php index daebb2ab2..2faf9723d 100644
class BP_Members_Component extends BP_Component { 39 39 buddypress()->plugin_dir, 40 40 array( 41 41 'adminbar_myaccount_order' => 20, 42 'search_query_arg' => 'members_search', 42 'search_query_arg' => 'members_search', 43 'features' => array( 'invitations' ) 43 44 ) 44 45 ); 45 46 } … … class BP_Members_Component extends BP_Component { 64 65 'blocks', 65 66 'widgets', 66 67 'cache', 68 'notifications', 69 'invitations', 67 70 ); 68 71 69 72 if ( bp_is_active( 'activity' ) ) { … … class BP_Members_Component extends BP_Component { 137 140 // Theme compatibility. 138 141 new BP_Registration_Theme_Compat(); 139 142 } 143 144 // Invitations. 145 if ( is_user_logged_in() && bp_is_user_members_invitations() ) { 146 if ( bp_is_user_members_invitations_send_screen() ) { 147 require $this->path . 'bp-members/screens/send-invites.php'; 148 } else { 149 require $this->path . 'bp-members/screens/list-invites.php'; 150 } 151 } 140 152 } 141 153 142 154 /** … … class BP_Members_Component extends BP_Component { 231 243 $bp->profile->slug = 'profile'; 232 244 $bp->profile->id = 'profile'; 233 245 } 246 247 /** Network Invitations ************************************************** 248 */ 249 250 $bp->members->invitations = new stdClass; 234 251 } 235 252 236 253 /** … … class BP_Members_Component extends BP_Component { 466 483 } 467 484 } 468 485 469 470 486 parent::setup_nav( $main_nav, $sub_nav ); 471 487 } 472 488 -
new file src/bp-members/classes/class-bp-members-invitation-manager.php
diff --git src/bp-members/classes/class-bp-members-invitation-manager.php src/bp-members/classes/class-bp-members-invitation-manager.php new file mode 100644 index 000000000..11647fcfe
- + 1 <?php 2 /** 3 * Group invitations class. 4 * 5 * @package BuddyPress 6 * @subpackage Core 7 * @since 7.0.0 8 */ 9 10 // Exit if accessed directly. 11 defined( 'ABSPATH' ) || exit; 12 13 /** 14 * Group invitations class. 15 * 16 * An extension of the core Invitations class that adapts the 17 * core logic to accommodate group invitation behavior. 18 * 19 * @since 7.0.0 20 */ 21 class BP_Members_Invitation_Manager extends BP_Invitation_Manager { 22 /** 23 * Construct parameters. 24 * 25 * @since 7.0.0 26 * 27 * @param array|string $args. 28 */ 29 public function __construct( $args = '' ) { 30 parent::__construct(); 31 } 32 33 /** 34 * This is where custom actions are added to run when notifications of an 35 * invitation or request need to be generated & sent. 36 * 37 * @since 7.0.0 38 * 39 * @param obj BP_Invitation $invitation The invitation to send. 40 * @return bool True on success, false on failure. 41 */ 42 public function run_send_action( BP_Invitation $invitation ) { 43 // Notify site admins of the pending request 44 if ( 'request' === $invitation->type ) { 45 // @TODO 46 return true; 47 // Notify the invitee of the invitation. 48 } else { 49 $inviter_ud = bp_core_get_core_userdata( $invitation->inviter_id ); 50 51 // @TODO: Handle unsubscribes differently since these are not members? 52 $unsubscribe_args = array( 53 'user_id' => 0, 54 'notification_type' => 'bp-members-invitation', 55 ); 56 $invite_url = esc_url( 57 add_query_arg( 58 array( 59 'inv' => $invitation->id, 60 'ih' => bp_members_invitations_get_hash( $invitation ), 61 ), bp_get_signup_page() 62 ) 63 ); 64 65 $args = array( 66 'tokens' => array( 67 'displayname' => $invitation->invitee_email, 68 'network.url' => get_site_url( bp_get_root_blog_id() ), 69 'network.name' => get_bloginfo( 'name' ), 70 'network.description' => get_bloginfo( 'description' ), 71 'inviter.name' => bp_core_get_userlink( $invitation->inviter_id, true, false, true ), 72 'inviter.url' => bp_core_get_user_domain( $invitation->inviter_id ), 73 'inviter.id' => $invitation->inviter_id, 74 'invites.url' => esc_url( $invite_url ), 75 'invite.message' => $invitation->content, 76 // @TODO: add unsubscribe method that isn't reliant on user being a member of the site. 77 // 'unsubscribe' => esc_url( bp_email_get_unsubscribe_link( $unsubscribe_args ) ), 78 ), 79 ); 80 81 return bp_send_email( 'bp-members-invitation', $invitation->invitee_email, $args ); 82 } 83 } 84 85 /** 86 * This is where custom actions are added to run when an invitation 87 * or request is accepted. 88 * 89 * @since 7.0.0 90 * 91 * @param string $type Are we accepting an invitation or request? 92 * @param array $r Parameters that describe the invitation being accepted. 93 * @return bool True on success, false on failure. 94 */ 95 public function run_acceptance_action( $type = 'invite', $r ) { 96 // If the user is already a member (because BP at one point allowed two invitations to 97 // slip through), return early. 98 99 if ( 'request' === $type ) { 100 /** 101 * Fires after a network membership request has been accepted. 102 * 103 * @since 1.0.0 104 * 105 * @param int $user_id ID of the user who accepted membership. 106 * @param int $group_id ID of the group that was accepted membership to. 107 */ 108 do_action( 'network_membership_request_accepted', $r['user_id'], $r['item_id'] ); 109 } else { 110 /** 111 * Fires after a user has accepted a group invite. 112 * 113 * @since 1.0.0 114 * @since 2.8.0 The $inviter_id arg was added. 115 * 116 * @param int $user_id ID of the user who accepted the membership invite. 117 * @param int $inviter_id ID of the user who invited this user to the group. 118 */ 119 do_action( 'network_membership_invite_accepted', $r['user_id'], $inviter_id ); 120 } 121 122 123 return true; 124 } 125 126 /** 127 * Should this invitation be created? 128 * 129 * @since 7.0.0 130 * 131 * @param array $args. 132 * @return bool 133 */ 134 public function allow_invitation( $args ) { 135 // Does the inviter have this capability? 136 if ( ! bp_user_can( $args['inviter_id'], 'bp_members_send_invitation' ) ) { 137 return false; 138 } 139 140 // Is the invited user eligible to receive an invitation? Hasn't opted out? 141 if ( ! bp_user_can( 0, 'bp_members_receive_invitation', $args ) ) { 142 return false; 143 } 144 145 return true; 146 } 147 148 /** 149 * Should this request be created? 150 * 151 * @since 7.0.0 152 * 153 * @param array $args. 154 * @return bool. 155 */ 156 public function allow_request( $args ) { 157 // Does the requester have this capability? 158 if ( ! bp_user_can( 0, 'bp_network_request_membership', $args ) ) { 159 return false; 160 } 161 162 return true; 163 } 164 } -
new file src/bp-members/classes/class-bp-members-invitations-list-table.php
diff --git src/bp-members/classes/class-bp-members-invitations-list-table.php src/bp-members/classes/class-bp-members-invitations-list-table.php new file mode 100644 index 000000000..dcdccc0b7
- + 1 <?php 2 /** 3 * BuddyPress Members List Table class. 4 * 5 * @package BuddyPress 6 * @subpackage MembersAdminClasses 7 * @since 2.3.0 8 */ 9 10 // Exit if accessed directly. 11 defined( 'ABSPATH' ) || exit; 12 13 /** 14 * List table class for signups admin page. 15 * 16 * @since 2.0.0 17 */ 18 class BP_Members_Invitations_List_Table extends WP_Users_List_Table { 19 20 /** 21 * Signup counts. 22 * 23 * @since 2.0.0 24 * 25 * @var int 26 */ 27 public $total_items = 0; 28 29 /** 30 * Constructor. 31 * 32 * @since 2.0.0 33 */ 34 public function __construct() { 35 // Define singular and plural labels, as well as whether we support AJAX. 36 parent::__construct( array( 37 'ajax' => false, 38 'plural' => 'invitations', 39 'singular' => 'invitation', 40 'screen' => get_current_screen()->id, 41 ) ); 42 } 43 44 /** 45 * Set up items for display in the list table. 46 * 47 * Handles filtering of data, sorting, pagination, and any other data 48 * manipulation required prior to rendering. 49 * 50 * @since 2.0.0 51 */ 52 public function prepare_items() { 53 global $usersearch; 54 55 $search = isset( $_REQUEST['s'] ) ? $_REQUEST['s'] : ''; 56 $per_page = $this->get_items_per_page( str_replace( '-', '_', "{$this->screen->id}_per_page" ) ); 57 $paged = $this->get_pagenum(); 58 59 $args = array( 60 'invite_sent' => 'all', 61 'accepted' => 'all', 62 'search_terms' => $search, 63 'order_by' => 'date_modified', 64 'sort_order' => 'DESC', 65 'page' => $paged, 66 'per_page' => $per_page, 67 ); 68 69 if ( isset( $_REQUEST['orderby'] ) ) { 70 $args['order_by'] = $_REQUEST['orderby']; 71 } 72 73 if ( isset( $_REQUEST['order'] ) ) { 74 $args['sort_order'] = $_REQUEST['order']; 75 } 76 77 $invites_class = new BP_Members_Invitation_Manager(); 78 $this->items = $invites_class->get_invitations( $args ); 79 $this->total_items = $invites_class->get_invitations_total_count( $args ); 80 81 $this->set_pagination_args( array( 82 'total_items' => $this->total_items, 83 'per_page' => $per_page, 84 ) ); 85 } 86 87 /** 88 * Display the users screen views 89 * 90 * @since 2.5.0 91 * 92 * @global string $role The name of role the users screens is filtered by 93 */ 94 public function views() { 95 global $role; 96 97 // Used to reset the role. 98 $reset_role = $role; 99 100 // Temporarly set the role to registered. 101 $role = 'registered'; 102 103 // Used to reset the screen id once views are displayed. 104 $reset_screen_id = $this->screen->id; 105 106 // Temporarly set the screen id to the users one. 107 $this->screen->id = 'users'; 108 109 // Use the parent function so that other plugins can safely add views. 110 parent::views(); 111 112 // Reset the role. 113 $role = $reset_role; 114 115 // Reset the screen id. 116 $this->screen->id = $reset_screen_id; 117 } 118 119 /** 120 * Get rid of the extra nav. 121 * 122 * WP_Users_List_Table will add an extra nav to change user's role. 123 * As we're dealing with signups, we don't need this. 124 * 125 * @since 2.0.0 126 * 127 * @param array $which Current table nav item. 128 */ 129 public function extra_tablenav( $which ) { 130 return; 131 } 132 133 /** 134 * Specific signups columns. 135 * 136 * @since 2.0.0 137 * 138 * @return array 139 */ 140 public function get_columns() { 141 142 /** 143 * Filters the single site Members signup columns. 144 * 145 * @since 2.0.0 146 * 147 * @param array $value Array of columns to display. 148 */ 149 return apply_filters( 'bp_members_signup_columns', array( 150 'cb' => '<input type="checkbox" />', 151 'username' => __( 'Username', 'buddypress' ), 152 'name' => __( 'Name', 'buddypress' ), 153 'email' => __( 'Email', 'buddypress' ), 154 'registered' => __( 'Registered', 'buddypress' ), 155 'date_sent' => __( 'Last Sent', 'buddypress' ), 156 'count_sent' => __( 'Emails Sent', 'buddypress' ) 157 ) ); 158 } 159 160 /** 161 * Specific bulk actions for signups. 162 * 163 * @since 2.0.0 164 */ 165 public function get_bulk_actions() { 166 $actions = array( 167 'activate' => _x( 'Activate', 'Pending signup action', 'buddypress' ), 168 'resend' => _x( 'Email', 'Pending signup action', 'buddypress' ), 169 ); 170 171 if ( current_user_can( 'delete_users' ) ) { 172 $actions['delete'] = __( 'Delete', 'buddypress' ); 173 } 174 175 return $actions; 176 } 177 178 /** 179 * The text shown when no items are found. 180 * 181 * Nice job, clean sheet! 182 * 183 * @since 2.0.0 184 */ 185 public function no_items() { 186 187 if ( bp_get_signup_allowed() ) { 188 esc_html_e( 'No pending accounts found.', 'buddypress' ); 189 } else { 190 $link = false; 191 192 // Specific case when BuddyPress is not network activated. 193 if ( is_multisite() && current_user_can( 'manage_network_users') ) { 194 $link = sprintf( '<a href="%1$s">%2$s</a>', esc_url( network_admin_url( 'settings.php' ) ), esc_html__( 'Edit settings', 'buddypress' ) ); 195 } elseif ( current_user_can( 'manage_options' ) ) { 196 $link = sprintf( '<a href="%1$s">%2$s</a>', esc_url( bp_get_admin_url( 'options-general.php' ) ), esc_html__( 'Edit settings', 'buddypress' ) ); 197 } 198 199 /* translators: %s: url to site settings */ 200 printf( __( 'Registration is disabled. %s', 'buddypress' ), $link ); 201 } 202 203 } 204 205 /** 206 * The columns signups can be reordered with. 207 * 208 * @since 2.0.0 209 */ 210 public function get_sortable_columns() { 211 return array( 212 'username' => 'login', 213 'email' => 'email', 214 'registered' => 'signup_id', 215 ); 216 } 217 218 /** 219 * Display signups rows. 220 * 221 * @since 2.0.0 222 */ 223 public function display_rows() { 224 $style = ''; 225 foreach ( $this->items as $userid => $signup_object ) { 226 227 // Avoid a notice error appearing since 4.3.0. 228 if ( isset( $signup_object->id ) ) { 229 $signup_object->ID = $signup_object->id; 230 } 231 232 $style = ( ' class="alternate"' == $style ) ? '' : ' class="alternate"'; 233 echo "\n\t" . $this->single_row( $signup_object, $style ); 234 } 235 } 236 237 /** 238 * Display a signup row. 239 * 240 * @since 2.0.0 241 * 242 * @see WP_List_Table::single_row() for explanation of params. 243 * 244 * @param object|null $signup_object Signup user object. 245 * @param string $style Styles for the row. 246 * @param string $role Role to be assigned to user. 247 * @param int $numposts Numper of posts. 248 * @return void 249 */ 250 public function single_row( $signup_object = null, $style = '', $role = '', $numposts = 0 ) { 251 echo '<tr' . $style . ' id="signup-' . esc_attr( $signup_object->id ) . '">'; 252 echo $this->single_row_columns( $signup_object ); 253 echo '</tr>'; 254 } 255 256 /** 257 * Markup for the checkbox used to select items for bulk actions. 258 * 259 * @since 2.0.0 260 * 261 * @param object|null $signup_object The signup data object. 262 */ 263 public function column_cb( $signup_object = null ) { 264 ?> 265 <label class="screen-reader-text" for="signup_<?php echo intval( $signup_object->id ); ?>"><?php 266 /* translators: accessibility text */ 267 printf( esc_html__( 'Select user: %s', 'buddypress' ), $signup_object->user_login ); 268 ?></label> 269 <input type="checkbox" id="signup_<?php echo intval( $signup_object->id ) ?>" name="allsignups[]" value="<?php echo esc_attr( $signup_object->id ) ?>" /> 270 <?php 271 } 272 273 /** 274 * The row actions (delete/activate/email). 275 * 276 * @since 2.0.0 277 * 278 * @param object|null $signup_object The signup data object. 279 */ 280 public function column_username( $signup_object = null ) { 281 $avatar = get_avatar( $signup_object->user_email, 32 ); 282 283 // Activation email link. 284 $email_link = add_query_arg( 285 array( 286 'page' => 'bp-signups', 287 'signup_id' => $signup_object->id, 288 'action' => 'resend', 289 ), 290 bp_get_admin_url( 'users.php' ) 291 ); 292 293 // Activate link. 294 $activate_link = add_query_arg( 295 array( 296 'page' => 'bp-signups', 297 'signup_id' => $signup_object->id, 298 'action' => 'activate', 299 ), 300 bp_get_admin_url( 'users.php' ) 301 ); 302 303 // Delete link. 304 $delete_link = add_query_arg( 305 array( 306 'page' => 'bp-signups', 307 'signup_id' => $signup_object->id, 308 'action' => 'delete', 309 ), 310 bp_get_admin_url( 'users.php' ) 311 ); 312 313 echo $avatar . sprintf( '<strong><a href="%1$s" class="edit">%2$s</a></strong><br/>', esc_url( $activate_link ), $signup_object->user_login ); 314 315 $actions = array(); 316 317 $actions['activate'] = sprintf( '<a href="%1$s">%2$s</a>', esc_url( $activate_link ), __( 'Activate', 'buddypress' ) ); 318 $actions['resend'] = sprintf( '<a href="%1$s">%2$s</a>', esc_url( $email_link ), __( 'Email', 'buddypress' ) ); 319 320 if ( current_user_can( 'delete_users' ) ) { 321 $actions['delete'] = sprintf( '<a href="%1$s" class="delete">%2$s</a>', esc_url( $delete_link ), __( 'Delete', 'buddypress' ) ); 322 } 323 324 /** 325 * Filters the multisite row actions for each user in list. 326 * 327 * @since 2.0.0 328 * 329 * @param array $actions Array of actions and corresponding links. 330 * @param object $signup_object The signup data object. 331 */ 332 $actions = apply_filters( 'bp_members_ms_signup_row_actions', $actions, $signup_object ); 333 334 echo $this->row_actions( $actions ); 335 } 336 337 /** 338 * Display user name, if any. 339 * 340 * @since 2.0.0 341 * 342 * @param object|null $signup_object The signup data object. 343 */ 344 public function column_name( $signup_object = null ) { 345 echo esc_html( $signup_object->user_name ); 346 } 347 348 /** 349 * Display user email. 350 * 351 * @since 2.0.0 352 * 353 * @param object|null $signup_object The signup data object. 354 */ 355 public function column_email( $signup_object = null ) { 356 printf( '<a href="mailto:%1$s">%2$s</a>', esc_attr( $signup_object->user_email ), esc_html( $signup_object->user_email ) ); 357 } 358 359 /** 360 * Display registration date. 361 * 362 * @since 2.0.0 363 * 364 * @param object|null $signup_object The signup data object. 365 */ 366 public function column_registered( $signup_object = null ) { 367 echo mysql2date( 'Y/m/d', $signup_object->registered ); 368 } 369 370 /** 371 * Display the last time an activation email has been sent. 372 * 373 * @since 2.0.0 374 * 375 * @param object|null $signup_object The signup data object. 376 */ 377 public function column_date_sent( $signup_object = null ) { 378 echo mysql2date( 'Y/m/d', $signup_object->date_sent ); 379 } 380 381 /** 382 * Display number of time an activation email has been sent. 383 * 384 * @since 2.0.0 385 * 386 * @param object|null $signup_object Signup object instance. 387 */ 388 public function column_count_sent( $signup_object = null ) { 389 echo absint( $signup_object->count_sent ); 390 } 391 392 /** 393 * Allow plugins to add their custom column. 394 * 395 * @since 2.1.0 396 * 397 * @param object|null $signup_object The signup data object. 398 * @param string $column_name The column name. 399 * @return string 400 */ 401 function column_default( $signup_object = null, $column_name = '' ) { 402 403 /** 404 * Filters the single site custom columns for plugins. 405 * 406 * @since 2.1.0 407 * 408 * @param string $column_name The column name. 409 * @param object $signup_object The signup data object. 410 */ 411 return apply_filters( 'bp_members_signup_custom_column', '', $column_name, $signup_object ); 412 } 413 } -
new file src/bp-members/classes/class-bp-members-invitations-template.php
diff --git src/bp-members/classes/class-bp-members-invitations-template.php src/bp-members/classes/class-bp-members-invitations-template.php new file mode 100644 index 000000000..b8fcebd76
- + 1 <?php 2 /** 3 * BuddyPress Members Invitation Template Loop Class. 4 * 5 * @package BuddyPress 6 * @subpackage TonificationsTemplate 7 * @since 1.9.0 8 */ 9 10 // Exit if accessed directly. 11 defined( 'ABSPATH' ) || exit; 12 13 /** 14 * The main network_invitations template loop class. 15 * 16 * Responsible for loading a group of network_invitations into a loop for display. 17 * 18 * @since 1.9.0 19 */ 20 class BP_Members_Invitations_Template { 21 22 /** 23 * The loop iterator. 24 * 25 * @since 1.9.0 26 * @var int 27 */ 28 public $current_invitation = -1; 29 30 /** 31 * The number of network_invitations returned by the paged query. 32 * 33 * @since 1.9.0 34 * @var int 35 */ 36 public $current_invitation_count; 37 38 /** 39 * Total number of network_invitations matching the query. 40 * 41 * @since 1.9.0 42 * @var int 43 */ 44 public $total_invitation_count; 45 46 /** 47 * Array of network invitations located by the query. 48 * 49 * @since 1.9.0 50 * @var array 51 */ 52 public $invitations; 53 54 /** 55 * The invitation object currently being iterated on. 56 * 57 * @since 1.9.0 58 * @var object 59 */ 60 public $invitation; 61 62 /** 63 * A flag for whether the loop is currently being iterated. 64 * 65 * @since 1.9.0 66 * @var bool 67 */ 68 public $in_the_loop; 69 70 /** 71 * The ID of the user to whom the displayed network_invitations were sent. 72 * 73 * @since 1.9.0 74 * @var int 75 */ 76 public $user_id; 77 78 /** 79 * The ID of the user to whom the displayed network_invitations belong. 80 * 81 * @since 1.9.0 82 * @var int 83 */ 84 public $inviter_id; 85 86 /** 87 * The page number being requested. 88 * 89 * @since 1.9.0 90 * @var int 91 */ 92 public $pag_page; 93 94 /** 95 * The $_GET argument used in URLs for determining pagination. 96 * 97 * @since 1.9.0 98 * @var int 99 */ 100 public $pag_arg; 101 102 /** 103 * The number of items to display per page of results. 104 * 105 * @since 1.9.0 106 * @var int 107 */ 108 public $pag_num; 109 110 /** 111 * An HTML string containing pagination links. 112 * 113 * @since 1.9.0 114 * @var string 115 */ 116 public $pag_links; 117 118 /** 119 * A string to match against. 120 * 121 * @since 1.9.0 122 * @var string 123 */ 124 public $search_terms; 125 126 /** 127 * A database column to order the results by. 128 * 129 * @since 1.9.0 130 * @var string 131 */ 132 public $order_by; 133 134 /** 135 * The direction to sort the results (ASC or DESC). 136 * 137 * @since 1.9.0 138 * @var string 139 */ 140 public $sort_order; 141 142 /** 143 * Array of variables used in this invitation query. 144 * 145 * @since 2.2.2 146 * @var array 147 */ 148 public $query_vars; 149 150 /** 151 * Constructor method. 152 * 153 * @see bp_has_members_invitations() For information on the array format. 154 * 155 * @since 1.9.0 156 * 157 * @param array $args { 158 * An array of arguments. See {@link bp_has_members_invitations()} 159 * for more details. 160 * } 161 */ 162 public function __construct( $args = array() ) { 163 164 // Parse arguments. 165 $r = wp_parse_args( $args, array( 166 'id' => false, 167 'user_id' => false, 168 'inviter_id' => false, 169 'invitee_email' => false, 170 'item_id' => false, 171 'type' => 'invite', 172 'invite_sent' => 'all', 173 'accepted' => 'all', 174 'search_terms' => '', 175 'order_by' => 'date_modified', 176 'sort_order' => 'DESC', 177 'page' => 1, 178 'per_page' => 25, 179 'fields' => 'all', 180 'page_arg' => 'ipage', 181 ) ); 182 183 // Sort order direction. 184 $orders = array( 'ASC', 'DESC' ); 185 if ( ! empty( $_GET['sort_order'] ) && in_array( $_GET['sort_order'], $orders ) ) { 186 $r['sort_order'] = $_GET['sort_order']; 187 } else { 188 $r['sort_order'] = in_array( $r['sort_order'], $orders ) ? $r['sort_order'] : 'DESC'; 189 } 190 191 // Setup variables. 192 $this->pag_arg = sanitize_key( $r['page_arg'] ); 193 $this->pag_page = bp_sanitize_pagination_arg( $this->pag_arg, $r['page'] ); 194 $this->pag_num = bp_sanitize_pagination_arg( 'num', $r['per_page'] ); 195 $this->user_id = $r['user_id']; 196 $this->search_terms = $r['search_terms']; 197 $this->order_by = $r['order_by']; 198 $this->sort_order = $r['sort_order']; 199 $this->query_vars = array( 200 'id' => $r['id'], 201 'user_id' => $r['user_id'], 202 'inviter_id' => $r['inviter_id'], 203 'invitee_email' => $r['invitee_email'], 204 'item_id' => $r['item_id'], 205 'type' => $r['type'], 206 'invite_sent' => $r['invite_sent'], 207 'accepted' => $r['accepted'], 208 'search_terms' => $this->search_terms, 209 'order_by' => $this->order_by, 210 'sort_order' => $this->sort_order, 211 'page' => $this->pag_page, 212 'per_page' => $this->pag_num, 213 ); 214 215 // Setup the network_invitations to loop through. 216 $invites_class = new BP_Members_Invitation_Manager(); 217 218 $this->invitations = $invites_class->get_invitations( $this->query_vars ); 219 $this->current_invitation_count = count( $this->invitations ); 220 $this->total_invitation_count = $invites_class->get_invitations_total_count( $this->query_vars ); 221 222 if ( (int) $this->total_invitation_count && (int) $this->pag_num ) { 223 $add_args = array( 224 'sort_order' => $this->sort_order, 225 ); 226 227 $this->pag_links = paginate_links( array( 228 'base' => add_query_arg( $this->pag_arg, '%#%' ), 229 'format' => '', 230 'total' => ceil( (int) $this->total_invitation_count / (int) $this->pag_num ), 231 'current' => $this->pag_page, 232 'prev_text' => _x( '←', 'Network invitation pagination previous text', 'buddypress' ), 233 'next_text' => _x( '→', 'Network invitation pagination next text', 'buddypress' ), 234 'mid_size' => 1, 235 'add_args' => $add_args, 236 ) ); 237 } 238 } 239 240 /** 241 * Whether there are network_invitations available in the loop. 242 * 243 * @since 1.9.0 244 * 245 * @see bp_has_members_invitations() 246 * 247 * @return bool True if there are items in the loop, otherwise false. 248 */ 249 public function has_invitations() { 250 if ( $this->current_invitation_count ) { 251 return true; 252 } 253 254 return false; 255 } 256 257 /** 258 * Set up the next invitation and iterate index. 259 * 260 * @since 1.9.0 261 * 262 * @return object The next invitation to iterate over. 263 */ 264 public function next_invitation() { 265 266 $this->current_invitation++; 267 268 $this->invitation = $this->invitations[ $this->current_invitation ]; 269 270 return $this->invitation; 271 } 272 273 /** 274 * Rewind the blogs and reset blog index. 275 * 276 * @since 1.9.0 277 */ 278 public function rewind_invitations() { 279 280 $this->current_invitation = -1; 281 282 if ( $this->current_invitation_count > 0 ) { 283 $this->invitation = $this->invitations[0]; 284 } 285 } 286 287 /** 288 * Whether there are network_invitations left in the loop to iterate over. 289 * 290 * This method is used by {@link bp_network_invitations()} as part of the 291 * while loop that controls iteration inside the network_invitations loop, eg: 292 * while ( bp_network_invitations() ) { ... 293 * 294 * @since 1.9.0 295 * 296 * @see bp_network_invitations() 297 * 298 * @return bool True if there are more network_invitations to show, 299 * otherwise false. 300 */ 301 public function invitations() { 302 303 if ( $this->current_invitation + 1 < $this->current_invitation_count ) { 304 return true; 305 306 } elseif ( $this->current_invitation + 1 == $this->current_invitation_count ) { 307 308 /** 309 * Fires right before the rewinding of invitation posts. 310 * 311 * @since 1.9.0 312 */ 313 do_action( 'network_invitations_loop_end'); 314 315 $this->rewind_invitations(); 316 } 317 318 $this->in_the_loop = false; 319 return false; 320 } 321 322 /** 323 * Set up the current invitation inside the loop. 324 * 325 * Used by {@link bp_the_invitation()} to set up the current 326 * invitation data while looping, so that template tags used during 327 * that iteration make reference to the current invitation. 328 * 329 * @since 1.9.0 330 * 331 * @see bp_the_invitation() 332 */ 333 public function the_invitation() { 334 $this->in_the_loop = true; 335 $this->invitation = $this->next_invitation(); 336 337 // Loop has just started. 338 if ( 0 === $this->current_invitation ) { 339 340 /** 341 * Fires if the current invitation item is the first in the invitation loop. 342 * 343 * @since 1.9.0 344 */ 345 do_action( 'network_invitations_loop_start' ); 346 } 347 } 348 } -
new file src/bp-members/screens/list-invites.php
diff --git src/bp-members/screens/list-invites.php src/bp-members/screens/list-invites.php new file mode 100644 index 000000000..d1eeddd8f
- + 1 <?php 2 /** 3 * Members: Sent Invitations Status 4 * 5 * @package BuddyPress 6 * @subpackage MembersScreens 7 * @since 6.0.0 8 */ 9 10 /** 11 * Catch and process the Send Invites page. 12 * 13 * @since 1.0.0 14 */ 15 function members_screen_list_sent_invites() { 16 17 /** 18 * Fires before the loading of template for the My Friends page. 19 * 20 * @since 1.0.0 21 */ 22 do_action( 'members_screen_list_sent_invites' ); 23 24 /** 25 * Filters the template used to display the My Friends page. 26 * 27 * @since 1.0.0 28 * 29 * @param string $template Path to the my friends template to load. 30 */ 31 bp_core_load_template( apply_filters( 'members_template_list_sent_invites', 'members/single/invitations' ) ); 32 } 33 34 /** 35 * Handle marking single notifications as unread. 36 * 37 * @since 1.9.0 38 * 39 * @return bool 40 */ 41 function bp_network_invitations_action_handling() { 42 43 // Bail if not the read screen. 44 if ( ! bp_is_user_members_invitations_list() ) { 45 return false; 46 } 47 48 // Get the action. 49 $action = ! empty( $_GET['action'] ) ? $_GET['action'] : ''; 50 $nonce = ! empty( $_GET['_wpnonce'] ) ? $_GET['_wpnonce'] : ''; 51 $id = ! empty( $_GET['invitation_id'] ) ? $_GET['invitation_id'] : ''; 52 53 // Bail if no action or no ID. 54 if ( empty( $action ) || empty( $id ) ) { 55 return false; 56 } 57 58 if ( 'cancel' === $action ) { 59 // Check the nonce and delete the invitation. 60 if ( bp_verify_nonce_request( 'bp_members_invitations_cancel_' . $id ) && bp_members_invitations_delete_by_id( $id ) ) { 61 bp_core_add_message( __( 'Invitation successfully canceled.', 'buddypress' ) ); 62 } else { 63 bp_core_add_message( __( 'There was a problem canceling that invitation.', 'buddypress' ), 'error' ); 64 } 65 } else if ( 'resend' === $action ) { 66 // Check the nonce and resend the invitation. 67 if ( bp_verify_nonce_request( 'bp_network_invitation_resend_' . $id ) && bp_members_invitation_resend_by_id( $id ) ) { 68 bp_core_add_message( __( 'Invitation successfully resent.', 'buddypress' ) ); 69 } else { 70 bp_core_add_message( __( 'There was a problem resending that invitation.', 'buddypress' ), 'error' ); 71 } 72 } else { 73 return false; 74 } 75 76 // Redirect. 77 $user_id = bp_displayed_user_id(); 78 bp_core_redirect( bp_get_members_invitations_list_invites_permalink( $user_id ) ); 79 } 80 add_action( 'bp_actions', 'bp_network_invitations_action_handling' ); -
src/bp-members/screens/register.php
diff --git src/bp-members/screens/register.php src/bp-members/screens/register.php index f954f3f41..5cb76a097 100644
function bp_core_screen_signup() { 42 42 43 43 $bp->signup->step = 'request-details'; 44 44 45 if ( !bp_get_signup_allowed() ) { 46 $bp->signup->step = 'registration-disabled'; 45 // Could the user be accepting an invitation? 46 $active_invite = false; 47 if ( bp_get_members_invitations_allowed() ) { 48 // Check to see if there's a valid invitation. 49 $maybe_invite = bp_get_members_invitation_from_request(); 50 if ( $maybe_invite->id ) { 51 $active_invite = true; 52 } 53 } 47 54 55 if ( ! bp_get_signup_allowed() && ! $active_invite ) { 56 $bp->signup->step = 'registration-disabled'; 48 57 // If the signup page is submitted, validate and save. 49 58 } elseif ( isset( $_POST['signup_submit'] ) && bp_verify_nonce_request( 'bp_new_signup' ) ) { 50 59 -
new file src/bp-members/screens/send-invites.php
diff --git src/bp-members/screens/send-invites.php src/bp-members/screens/send-invites.php new file mode 100644 index 000000000..61ddc0d3f
- + 1 <?php 2 /** 3 * Members: Send Invitations 4 * 5 * @package BuddyPress 6 * @subpackage MembersScreens 7 * @since 3.0.0 8 */ 9 10 /** 11 * Catch and process the Send Invites page. 12 * 13 * @since 1.0.0 14 */ 15 function members_screen_send_invites() { 16 17 /** 18 * Fires before the loading of template for the My Friends page. 19 * 20 * @since 1.0.0 21 */ 22 do_action( 'members_screen_send_invites' ); 23 24 /** 25 * Filters the template used to display the My Friends page. 26 * 27 * @since 1.0.0 28 * 29 * @param string $template Path to the my friends template to load. 30 */ 31 bp_core_load_template( apply_filters( 'members_template_send_invites', 'members/single/invitations' ) ); 32 } 33 34 /** 35 * Handle marking single notifications as unread. 36 * 37 * @since 1.9.0 38 * 39 * @return bool 40 */ 41 function bp_network_invitations_catch_send_action() { 42 43 // Bail if not the read screen. 44 if ( ! bp_is_user_members_invitations_send_screen() ) { 45 return false; 46 } 47 48 // Get the action. 49 $action = ! empty( $_REQUEST['action'] ) ? $_REQUEST['action'] : ''; 50 $nonce = ! empty( $_REQUEST['_wpnonce'] ) ? $_REQUEST['_wpnonce'] : ''; 51 $email = ! empty( $_REQUEST['invitee_email'] ) ? $_REQUEST['invitee_email'] : ''; 52 $message = ! empty( $_REQUEST['invite_message'] ) ? $_REQUEST['invite_message'] : ''; 53 54 // Bail if missing required info. 55 if ( ( 'send-invite' !== $action ) ) { 56 return false; 57 } 58 59 $invite_args = array( 60 'invitee_email' => $email, 61 'inviter_id' => bp_displayed_user_id(), 62 'content' => $message, 63 'send_invite' => 1 64 ); 65 66 // Check the nonce and delete the invitation. 67 if ( bp_verify_nonce_request( 'bp_network_invitation_send_' . bp_displayed_user_id() ) && bp_members_invitations_invite_user( $invite_args ) ) { 68 bp_core_add_message( __( 'Invitation successfully sent!', 'buddypress' ) ); 69 } else { 70 bp_core_add_message( __( 'There was a problem sending that invitation.', 'buddypress' ), 'error' ); 71 } 72 73 // Redirect. 74 $user_id = bp_displayed_user_id(); 75 bp_core_redirect( bp_get_members_invitations_send_invites_permalink( $user_id ) ); 76 } 77 add_action( 'bp_actions', 'bp_network_invitations_catch_send_action' ); 78 No newline at end of file -
src/bp-templates/bp-legacy/buddypress-functions.php
diff --git src/bp-templates/bp-legacy/buddypress-functions.php src/bp-templates/bp-legacy/buddypress-functions.php index f4a3e1016..e3d0f63fb 100644
function bp_legacy_theme_group_manage_members_add_search() { 2014 2014 <?php 2015 2015 endif; 2016 2016 } 2017 2018 /** 2019 * Modify welcome message in Legacy template pack when 2020 * community invitations are enabled. 2021 * 2022 * @since 7.0.0 2023 * 2024 * @return string $message The message text. 2025 */ 2026 function bp_members_invitations_add_legacy_welcome_message() { 2027 $message = bp_members_invitations_get_registration_welcome_message(); 2028 if ( $message ) { 2029 echo '<p>' . esc_html( $message ) . '</p>'; 2030 } 2031 } 2032 add_action( 'bp_before_register_page', 'bp_members_invitations_add_legacy_welcome_message' ); 2033 2034 2035 /** 2036 * Modify "registration disabled" message in Legacy template pack when 2037 * community invitations are enabled. 2038 * 2039 * @since 7.0.0 2040 * 2041 * @return string $message The message text. 2042 */ 2043 function bp_members_invitations_add_legacy_registration_disabled_message() { 2044 $message = bp_members_invitations_get_modified_registration_disabled_message(); 2045 if ( $message ) { 2046 echo '<p>' . esc_html( $message ) . '</p>'; 2047 } 2048 } 2049 add_action( 'bp_after_registration_disabled', 'bp_members_invitations_add_legacy_registration_disabled_message' ); -
src/bp-templates/bp-legacy/buddypress/members/single/home.php
diff --git src/bp-templates/bp-legacy/buddypress/members/single/home.php src/bp-templates/bp-legacy/buddypress/members/single/home.php index f56af6e9c..bed9da1bf 100644
89 89 elseif ( bp_is_user_notifications() ) : 90 90 bp_get_template_part( 'members/single/notifications' ); 91 91 92 elseif ( bp_is_user_members_invitations() ) : 93 bp_get_template_part( 'members/single/invitations' ); 94 92 95 elseif ( bp_is_user_settings() ) : 93 96 bp_get_template_part( 'members/single/settings' ); 94 97 -
new file src/bp-templates/bp-legacy/buddypress/members/single/invitations.php
diff --git src/bp-templates/bp-legacy/buddypress/members/single/invitations.php src/bp-templates/bp-legacy/buddypress/members/single/invitations.php new file mode 100644 index 000000000..0933b896d
- + 1 <?php 2 /** 3 * BuddyPress - Users Notifications 4 * 5 * @package BuddyPress 6 * @subpackage bp-legacy 7 * @version 3.0.0 8 */ 9 10 ?> 11 12 <div class="item-list-tabs no-ajax" id="subnav" aria-label="<?php esc_attr_e( 'Member secondary navigation', 'buddypress' ); ?>" role="navigation"> 13 <ul> 14 <?php bp_get_options_nav(); ?> 15 </ul> 16 </div> 17 18 <?php 19 switch ( bp_current_action() ) : 20 21 case 'send-invites' : 22 bp_get_template_part( 'members/single/invitations/send-invites' ); 23 break; 24 25 case 'list-invites' : 26 default : 27 bp_get_template_part( 'members/single/invitations/list-invites' ); 28 break; 29 30 endswitch; 31 -
new file src/bp-templates/bp-legacy/buddypress/members/single/invitations/invitations-loop.php
diff --git src/bp-templates/bp-legacy/buddypress/members/single/invitations/invitations-loop.php src/bp-templates/bp-legacy/buddypress/members/single/invitations/invitations-loop.php new file mode 100644 index 000000000..61bc68001
- + 1 <?php 2 /** 3 * BuddyPress - Members Invitations Loop 4 * 5 * @package BuddyPress 6 * @subpackage bp-legacy 7 * @version 3.0.0 8 */ 9 10 ?> 11 <form action="" method="post" id="invitations-bulk-management"> 12 <table class="invitations"> 13 <thead> 14 <tr> 15 <th class="icon"></th> 16 <th class="bulk-select-all"><input id="select-all-invitations" type="checkbox"><label class="bp-screen-reader-text" for="select-all-invitations"><?php 17 /* translators: accessibility text */ 18 _e( 'Select all', 'buddypress' ); 19 ?></label></th> 20 <th class="title"><?php _e( 'Invitee', 'buddypress' ); ?></th> 21 <th class="content"><?php _e( 'Message', 'buddypress' ); ?></th> 22 <th class="sent"><?php _e( 'Sent', 'buddypress' ); ?></th> 23 <th class="accepted"><?php _e( 'Accepted', 'buddypress' ); ?></th> 24 <th class="date"><?php _e( 'Date Modified', 'buddypress' ); ?></th> 25 <th class="actions"><?php _e( 'Actions', 'buddypress' ); ?></th> 26 </tr> 27 </thead> 28 29 <tbody> 30 31 <?php while ( bp_the_members_invitations() ) : bp_the_members_invitation(); ?> 32 33 <tr> 34 <td></td> 35 <td class="bulk-select-check"><label for="<?php bp_the_members_invitation_property( 'id' ); ?>"><input id="<?php bp_the_members_invitation_property( 'id' ); ?>" type="checkbox" name="network_invitations[]" value="<?php bp_the_members_invitation_property( 'id' ); ?>" class="invitation-check"><span class="bp-screen-reader-text"><?php 36 /* translators: accessibility text */ 37 _e( 'Select this invitation', 'buddypress' ); 38 ?></span></label></td> 39 <td class="invitation-invitee"><?php bp_the_members_invitation_property( 'invitee_email' ); ?></td> 40 <td class="invitation-content"><?php wptexturize( bp_the_members_invitation_property( 'content' ) ); ?></td> 41 <td class="invitation-sent"><?php bp_the_members_invitation_property( 'invite_sent' ); ?></td> 42 <td class="invitation-accepted"><?php bp_the_members_invitation_property( 'accepted' ); ?></td> 43 <td class="invitation-date-modified"><?php bp_the_members_invitation_property( 'date_modified' ); ?></td> 44 <td class="invitation-actions"><?php bp_the_members_invitation_action_links(); ?></td> 45 </tr> 46 47 <?php endwhile; ?> 48 49 </tbody> 50 </table> 51 52 <div class="invitations-options-nav"> 53 <?php // @TODO //bp_invitations_bulk_management_dropdown(); ?> 54 </div><!-- .invitations-options-nav --> 55 56 <?php wp_nonce_field( 'invitations_bulk_nonce', 'invitations_bulk_nonce' ); ?> 57 </form> -
new file src/bp-templates/bp-legacy/buddypress/members/single/invitations/list-invites.php
diff --git src/bp-templates/bp-legacy/buddypress/members/single/invitations/list-invites.php src/bp-templates/bp-legacy/buddypress/members/single/invitations/list-invites.php new file mode 100644 index 000000000..50810d424
- + 1 <?php 2 /** 3 * BuddyPress - Members Sent Network Invitations 4 * 5 * @package BuddyPress 6 * @subpackage bp-legacy 7 * @version 3.0.0 8 */ 9 ?> 10 11 <?php if ( bp_has_members_invitations() ) : ?> 12 13 <h2 class="bp-screen-reader-text"><?php 14 /* translators: accessibility text */ 15 _e( 'Invitations', 'buddypress' ); 16 ?></h2> 17 18 <div id="pag-top" class="pagination no-ajax"> 19 <div class="pag-count" id="invitations-count-top"> 20 <?php bp_members_invitations_pagination_count(); ?> 21 </div> 22 23 <div class="pagination-links" id="invitations-pag-top"> 24 <?php bp_members_invitations_pagination_links(); ?> 25 </div> 26 </div> 27 28 <?php bp_get_template_part( 'members/single/invitations/invitations-loop' ); ?> 29 30 <div id="pag-bottom" class="pagination no-ajax"> 31 <div class="pag-count" id="invitations-count-bottom"> 32 <?php bp_members_invitations_pagination_count(); ?> 33 </div> 34 35 <div class="pagination-links" id="invitations-pag-bottom"> 36 <?php bp_members_invitations_pagination_links(); ?> 37 </div> 38 </div> 39 40 <?php else : ?> 41 42 <p><?php _e( 'There are no invitations to display.', 'buddypress' ); ?></p> 43 44 <?php endif; -
new file src/bp-templates/bp-legacy/buddypress/members/single/invitations/send-invites.php
diff --git src/bp-templates/bp-legacy/buddypress/members/single/invitations/send-invites.php src/bp-templates/bp-legacy/buddypress/members/single/invitations/send-invites.php new file mode 100644 index 000000000..e3fec5519
- + 1 <?php 2 /** 3 * BuddyPress - Members Sent Network Invitations 4 * 5 * @package BuddyPress 6 * @subpackage bp-legacy 7 * @version 3.0.0 8 */ 9 ?> 10 <h2 class="bp-screen-reader-text"><?php 11 /* translators: accessibility text */ 12 _e( 'Send Invitations', 'buddypress' ); 13 ?></h2> 14 15 <form class="standard-form network-invitation-form" id="network-invitation-form" method="post"> 16 <label for="bp_network_invitation_invitee_email"><?php _e( 'Email address of new user', 'buddypress' ); ?></label> 17 <input id="bp_network_invitation_invitee_email" type="email" name="invitee_email" required="required"> 18 19 <label for="bp_network_invitation_message"><?php _e( 'Add a personalized message to the invitation (optional)', 'buddypress' ); ?></label> 20 <textarea id="bp_network_invitation_message" name="invite_message"></textarea> 21 22 <input type="hidden" name="action" value="send-invite"> 23 24 <?php wp_nonce_field( 'bp_network_invitation_send_' . bp_displayed_user_id() ) ?> 25 <p> 26 <input id="submit" type="submit" name="submit" class="submit" value="<?php esc_attr_e( 'Send Invitation', 'buddypress' ) ?>" /> 27 </p> 28 </form> -
src/bp-templates/bp-nouveau/buddypress-functions.php
diff --git src/bp-templates/bp-nouveau/buddypress-functions.php src/bp-templates/bp-nouveau/buddypress-functions.php index e2c6535e9..47db49706 100644
class BP_Nouveau extends BP_Theme_Compat { 195 195 // Set the BP Uri for the Ajax customizer preview. 196 196 add_filter( 'bp_uri', array( $this, 'customizer_set_uri' ), 10, 1 ); 197 197 198 // Modify "registration disabled" and welcome message if invitations are enabled. 199 add_action( 'bp_nouveau_feedback_messages', array( $this, 'filter_registration_messages' ), 99 ); 200 198 201 /** Override **********************************************************/ 199 202 200 203 /** … … class BP_Nouveau extends BP_Theme_Compat { 649 652 650 653 return $path; 651 654 } 655 /** 656 * Modify "registration disabled" message in Nouveau template pack. 657 * Modify welcome message in Nouveau template pack. 658 * 659 * @since 7.0.0 660 * 661 * @param array $messages The list of feedback messages. 662 * 663 * @return array $messages 664 */ 665 function filter_registration_messages( $messages ) { 666 // Change the "registration is disabled" message. 667 $disallowed_message = bp_members_invitations_get_modified_registration_disabled_message(); 668 if ( $disallowed_message ) { 669 $messages['registration-disabled']['message'] = $disallowed_message; 670 } 671 // Add information about invitations to the welcome block. 672 $welcome_message = bp_members_invitations_get_registration_welcome_message(); 673 if ( $welcome_message ) { 674 $messages['request-details']['message'] = $welcome_message . $messages['request-details']['message']; 675 } 676 return $messages; 677 } 652 678 } 653 679 654 680 /** -
new file src/bp-templates/bp-nouveau/buddypress/members/single/invitations.php
diff --git src/bp-templates/bp-nouveau/buddypress/members/single/invitations.php src/bp-templates/bp-nouveau/buddypress/members/single/invitations.php new file mode 100644 index 000000000..1cf1d8d6a
- + 1 <?php 2 /** 3 * BuddyPress - Users Groups 4 * 5 * @since 3.0.0 6 * @version 3.0.0 7 */ 8 ?> 9 10 <nav class="<?php bp_nouveau_single_item_subnav_classes(); ?>" id="subnav" role="navigation" aria-label="<?php esc_attr_e( 'Groups menu', 'buddypress' ); ?>"> 11 <ul class="subnav"> 12 13 <?php if ( bp_is_my_profile() ) : ?> 14 15 <?php bp_get_template_part( 'members/single/parts/item-subnav' ); ?> 16 17 <?php endif; ?> 18 19 </ul> 20 </nav><!-- .bp-navs --> 21 22 <?php bp_get_template_part( 'common/search-and-filters-bar' ); ?> 23 eh? 24 <?php 25 if ( 'sent-invites' === bp_current_action() ) { 26 echo "send tinvites"; 27 } else { 28 echo "default"; 29 30 } 31 -
src/class-buddypress.php
diff --git src/class-buddypress.php src/class-buddypress.php index 5464e5c4a..5b222cff2 100644
class BuddyPress { 615 615 'BP_REST_Attachments_Member_Avatar_Endpoint' => 'members', 616 616 'BP_REST_Attachments_Member_Cover_Endpoint' => 'members', 617 617 'BP_REST_Signup_Endpoint' => 'members', 618 'BP_Members_Invitation_Manager' => 'members', 619 'BP_Members_Invitations_Template' => 'members', 618 620 619 621 'BP_REST_Messages_Endpoint' => 'messages', 620 622