Ticket #8139: 8139.01.diff
File 8139.01.diff, 130.6 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..f53627acd 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_network_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..0c4be016c 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_network_invitations() { 191 ?> 192 <input id="bp-enable-network-invitations" name="bp-enable-network-invitations" type="checkbox" value="1" <?php checked( bp_get_network_invitations_allowed() ); ?> /> 193 <label for="bp-enable-network-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 do_action( 'bp_admin_settings_after_network_invitations' ); 199 } 200 185 201 /** XProfile ******************************************************************/ 186 202 187 203 /** -
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..f0de4e6ea 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_network_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_network_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 e659eace1..17f0b5d4c 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_network_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-network-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-network-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 $network_invitation = array( 3696 'description' => __( 'A site member has sent a site invitation to the recipient.', 'buddypress' ), 3697 'unsubscribe' => array( 3698 'meta_key' => 'notification_bp_network_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-network-invitation' => $network_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..dd5798290 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_network_invitations_component() { 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 Network 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 Network Invitations page. 2669 */ 2670 function bp_is_user_network_invitations() { 2671 return (bool) ( bp_is_user() && bp_is_network_invitations_component() ); 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_network_invitations_list() { 2684 return (bool) ( bp_is_user_network_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_network_invitations_send_screen() { 2697 return (bool) ( bp_is_user_network_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..b16046856 100644
class BP_Admin { 409 409 register_setting( 'buddypress', 'bp-disable-cover-image-uploads', 'intval' ); 410 410 } 411 411 412 // Network Invitations. 413 add_settings_field( 'bp-enable-network-invitations', __( 'Network Invitations', 'buddypress' ), 'bp_admin_setting_callback_network_invitations', 'buddypress', 'bp_members' ); 414 register_setting( 'buddypress', 'bp-enable-network-invitations', 'intval' ); 415 412 416 /* XProfile Section **************************************************/ 413 417 414 418 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..55c57e8b3 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-network-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..851d16eb8 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 3.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 'manage_network_membership_requests': 148 $retval = bp_user_can( $user_id, 'bp_moderate' ); 149 break; 150 case 'bp_network_send_invitation': 151 $retval = true; 152 break; 153 case 'bp_network_receive_invitation': 154 $retval = true; 155 // The invited user must not already be a member of the network. 156 if ( empty( $args['invitee_email'] ) || false !== get_user_by( 'email', $args['invitee_email'] ) ) { 157 $retval = false; 158 } 159 // The invited user must not have opted out from receiving invitations. 160 // @TODO: 161 162 163 break; 164 } 165 166 return $retval; 167 168 } 169 add_filter( 'bp_user_can', 'bp_members_user_can_filter', 10, 5 ); 170 171 function maybe_prevent_activation_emails( $usermeta ) { 172 // Stop the activation email from being sent if registration is by request only. 173 // $if "anyone can join is not true," 174 if ( true ) { 175 176 } 177 return $usermeta; 178 } 179 add_filter( 'bp_signup_usermeta', 'maybe_prevent_activation_emails', 10, 1 ); 180 181 /** 182 * Do not allow the new user to change the email address 183 * if they are accepting a network invitation. 184 * 185 * @since 7.0.0 186 * 187 * @param array $attributes The field attributes. 188 * @param string $name The field name. 189 * 190 * @return array $attributes The field attributes. 191 */ 192 function maybe_make_registration_email_input_readonly( $attributes, $name ) { 193 if ( 'email' === $name && bp_get_network_invitations_allowed() ) { 194 $invite = bp_get_network_invitation_from_request(); 195 if ( $invite->id ) { 196 $attributes['readonly'] = 'readonly'; 197 } 198 } 199 return $attributes; 200 } 201 add_filter( 'bp_get_form_field_attributes', 'maybe_make_registration_email_input_readonly', 10, 2 ); 202 203 /** 204 * Provide a more-specific welcome message if the new user 205 * is accepting a network invitation. 206 * 207 * @since 7.0.0 208 * 209 * @return string $message The message text. 210 */ 211 function bp_network_invitations_get_registration_welcome_message() { 212 $message = ''; 213 if ( ! bp_get_network_invitations_allowed() ) { 214 return $message; 215 } 216 $invite = bp_get_network_invitation_from_request(); 217 if ( ! $invite->id ) { 218 return $message; 219 } 220 221 // Fetch the display names of all inviters to personalize the welcome message. 222 $all_invites = bp_network_get_invites( array( 'invitee_email' => $invite->invitee_email ) ); 223 $inviters = array(); 224 foreach ( $all_invites as $inv ) { 225 $inviters[] = bp_core_get_user_displayname( $inv->inviter_id ); 226 } 227 228 if ( ! empty( $inviters ) ) { 229 $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 ) ); 230 } else { 231 $message = __( 'Welcome! You’ve been invited to join the site. ', 'buddypress' ); 232 } 233 return $message; 234 } 235 236 /** 237 * Provide a more-specific "registration is disabled" message 238 * if registration is available by invitation only. 239 * Also provide failure note if new user is trying to accept 240 * a network invitation but there's a problem. 241 * 242 * @since 7.0.0 243 * 244 * @return string $message The message text. 245 */ 246 function bp_network_invitations_get_modified_registration_disabled_message() { 247 $message = ''; 248 if ( bp_get_network_invitations_allowed() ) { 249 $message = __( 'Member registration is allowed by invitation only.', 'buddypress' ); 250 // Is the user trying to accept an invitation but something is wrong? 251 if ( ! empty( $_GET['inv'] ) ) { 252 $message .= __( ' It looks like there is a problem with your invitation. Please try again.', 'buddypress' ); 253 } 254 } 255 return $message; 256 } 257 258 /** 259 * Modify welcome message in Legacy template pack. 260 * 261 * @since 7.0.0 262 * 263 * @return string $message The message text. 264 */ 265 function bp_network_invitations_add_legacy_welcome_message() { 266 if ( 'legacy' !== bp_get_theme_package_id() ) { 267 return; 268 } 269 $message = bp_network_invitations_get_registration_welcome_message(); 270 if ( $message ) { 271 echo '<p>' . esc_html( $message ) . '</p>'; 272 } 273 } 274 add_action( 'bp_before_register_page', 'bp_network_invitations_add_legacy_welcome_message' ); 275 276 /** 277 * Modify "registration disabled" message in Legacy template pack. 278 * 279 * @since 7.0.0 280 * 281 * @return string $message The message text. 282 */ 283 function bp_network_invitations_add_legacy_registration_disabled_message() { 284 if ( 'legacy' !== bp_get_theme_package_id() ) { 285 return; 286 } 287 $message = bp_network_invitations_get_modified_registration_disabled_message(); 288 if ( $message ) { 289 echo "<p>{$message}</p>"; 290 } 291 } 292 add_action( 'bp_after_registration_disabled', 'bp_network_invitations_add_legacy_registration_disabled_message' ); 293 294 /** 295 * Modify "registration disabled" message in Nouveau template pack. 296 * Modify welcome message in Nouveau template pack. 297 * 298 * @since 7.0.0 299 * 300 * @param array $messages The list of feedback messages. 301 * 302 * @return array $messages 303 */ 304 function bp_network_invitations_filter_nouveau_registration_messages( $messages ) { 305 // Change the "registration is disabled" message. 306 $disallowed_message = bp_network_invitations_get_modified_registration_disabled_message(); 307 if ( $disallowed_message ) { 308 $messages['registration-disabled']['message'] = $disallowed_message; 309 } 310 // Add information about invitations to the welcome block. 311 $welcome_message = bp_network_invitations_get_registration_welcome_message(); 312 if ( $welcome_message ) { 313 $messages['request-details']['message'] = $welcome_message . $messages['request-details']['message']; 314 } 315 return $messages; 316 } 317 add_action( 'bp_nouveau_feedback_messages', 'bp_network_invitations_filter_nouveau_registration_messages', 99 ); -
src/bp-members/bp-members-functions.php
diff --git src/bp-members/bp-members-functions.php src/bp-members/bp-members-functions.php index 29741ebaa..fbb721cfd 100644
function bp_members_avatar_upload_dir( $directory = 'avatars', $user_id = 0 ) { 3044 3044 'error' => false 3045 3045 ) ); 3046 3046 } 3047 3048 /** 3049 * Get invitations to the BP network filtered by arguments. 3050 * 3051 * @since 7.0.0 3052 * 3053 * @param array $args Invitation arguments. 3054 * See BP_Invitation::get() for list. 3055 * 3056 * @return array $invites Matching BP_Invitation objects. 3057 */ 3058 function bp_network_get_invites( $args = array() ) { 3059 $invites_class = new BP_Network_Invitation_Manager(); 3060 return $invites_class->get_invitations( $args ); 3061 } 3062 3063 /** 3064 * Invite a user to a network. 3065 * 3066 * @since 7.0.0 3067 * 3068 * @param array|string $args { 3069 * Array of arguments. 3070 * @type int $invitee_email Email address of the user being invited. 3071 * @type int $network_id ID of the network to which the user is being invited. 3072 * @type int $inviter_id Optional. ID of the inviting user. Default: 3073 * ID of the logged-in user. 3074 * @type string $date_modified Optional. Modified date for the invitation. 3075 * Default: current date/time. 3076 * @type string $content Optional. Message to invitee. 3077 * @type bool $send_invite Optional. Whether the invitation should be 3078 * sent now. Default: false. 3079 * } 3080 * @return bool True on success, false on failure. 3081 */ 3082 function bp_network_invite_user( $args ) { 3083 $r = bp_parse_args( $args, array( 3084 'invitee_email' => '', 3085 'network_id' => get_current_network_id(), 3086 'inviter_id' => bp_loggedin_user_id(), 3087 'date_modified' => bp_core_current_time(), 3088 'content' => '', 3089 'send_invite' => 0 3090 ), 'bp_network_invite_user' ); 3091 3092 $inv_args = array( 3093 'invitee_email' => $r['invitee_email'], 3094 'item_id' => $r['network_id'], 3095 'inviter_id' => $r['inviter_id'], 3096 'date_modified' => $r['date_modified'], 3097 'content' => $r['content'], 3098 'send_invite' => $r['send_invite'] 3099 ); 3100 3101 // Create the invitataion. 3102 $invites_class = new BP_Network_Invitation_Manager(); 3103 $created = $invites_class->add_invitation( $inv_args ); 3104 3105 /** 3106 * Fires after the creation of a new network invite. 3107 * 3108 * @since 7.0.0 3109 * 3110 * @param array $r Array of parsed arguments for the network invite. 3111 * @param int|bool $created The ID of the invitation or false if it couldn't be created. 3112 */ 3113 do_action( 'bp_network_invite_user', $r, $created ); 3114 3115 return $created; 3116 } 3117 3118 /** 3119 * Resend a network invitation email by id. 3120 * 3121 * @since 7.0.0 3122 * 3123 * @param int $id ID of the invitation to resend. 3124 * @return bool True on success, false on failure. 3125 */ 3126 function bp_network_invitation_resend_by_id( $id = 0 ) { 3127 3128 // Find the invitation before deleting it. 3129 $existing_invite = new BP_Invitation( $id ); 3130 $invites_class = new BP_Network_Invitation_Manager(); 3131 $success = $invites_class->send_invitation_by_id( $id ); 3132 3133 error_log( 'send by id '.print_r( $success, true ) ); 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_network_invite_resent_invitation', $existing_invite ); 3147 3148 return $success; 3149 } 3150 3151 /** 3152 * Delete a network 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_network_invitation_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_Network_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 network invite. 3174 * 3175 * @since 7.0.0 3176 * 3177 * @param BP_Invitation $existing_invite The invitation to be deleted. 3178 */ 3179 do_action( 'bp_network_invite_canceled_invitation', $existing_invite ); 3180 } else if ( ! $existing_invite->accepted ) { 3181 /** 3182 * Fires after the deletion of a sent, but not yet accepted, network invite. 3183 * 3184 * @since 7.0.0 3185 * 3186 * @param BP_Invitation $existing_invite The invitation to be deleted. 3187 */ 3188 do_action( 'bp_network_invite_revoked_invitation', $existing_invite ); 3189 } else { 3190 /** 3191 * Fires after the deletion of a sent and accepted network invite. 3192 * 3193 * @since 7.0.0 3194 * 3195 * @param BP_Invitation $existing_invite The invitation to be deleted. 3196 */ 3197 do_action( 'bp_network_invite_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 on success, false on failure. 3218 */ 3219 function bp_network_invitation_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 ), 'bp_network_invite_user' ); 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_Network_Invitation_Manager(); 3238 $invites = $invites_class->get_invitations( $inv_args ); 3239 3240 // Loop through, deleting each invitation. 3241 foreach ( $invites as $invite ) { 3242 /** 3243 * Fires after the deletion of a sent network invite. 3244 * 3245 * @since 7.0.0 3246 * 3247 * @param array $r Array of parsed arguments for the network invite. 3248 * @param int|bool $created The ID of the invitation or false if it couldn't be created. 3249 */ 3250 do_action( 'bp_network_invite_revoked_invitation', $inv_args, $created ); 3251 } 3252 3253 3254 3255 return $invites; 3256 } 3257 3258 /** 3259 * Get hash based on details of a network invitation and the inviter. 3260 * 3261 * @since 7.0.0 3262 * 3263 * @param BP_Invitation object $invitation Invitation to create hash from. 3264 * 3265 * @return string $hash Calculated sha1 hash. 3266 */ 3267 function bp_network_invitation_get_hash( BP_Invitation $invitation ) { 3268 $hash = false; 3269 3270 if ( ! empty( $invitation->id ) ) { 3271 $inviter_ud = get_userdata( $invitation->inviter_id ); 3272 if ( $inviter_ud ) { 3273 /* 3274 * Use some inviter details as part of the salt so that invitations from 3275 * users who are subsequently marked as spam will be invalidated. 3276 */ 3277 $hash = hash_hmac( 'sha1', "{$invitation->inviter_id}:{$invitation->date_modified}", "{$inviter_ud->user_status}:{$inviter_ud->user_registered}" ); 3278 } 3279 } 3280 3281 // If there's a problem, return a string that will change and thus fail. 3282 if ( ! $hash ) { 3283 $hash = wp_generate_password( 32, false ); 3284 } 3285 3286 /** 3287 * Filters the hash calculated by the invitation details. 3288 * 3289 * @since 7.0.0 3290 * 3291 * @param string $hash Calculated sha1 hash. 3292 * @param BP_Invitation object $invitation Invitation hash was created from. 3293 */ 3294 return apply_filters( 'bp_network_invitation_get_hash', $hash, $invitation ); 3295 } 3296 3297 /** 3298 * Get the current invitation specified by the $_GET parameters. 3299 * 3300 * @since 7.0.0 3301 * 3302 * @return BP_Invitation $invite Invitation specified by the $_GET parameters. 3303 */ 3304 function bp_get_network_invitation_from_request() { 3305 $invites_class = new BP_Network_Invitation_Manager(); 3306 $invite = $invites_class->get_by_id( 0 ); 3307 3308 if ( bp_get_network_invitations_allowed() && ! empty( $_GET['inv'] ) ) { 3309 // Check to make sure the passed hash matches a calculated hash. 3310 $maybe_invite = $invites_class->get_by_id( absint( $_GET['inv'] ) ); 3311 $hash = bp_network_invitation_get_hash( $maybe_invite ); 3312 if ( $_GET['ih'] === $hash ) { 3313 $invite = $maybe_invite; 3314 } 3315 } 3316 3317 /** 3318 * Filters the invitation specified by the $_GET parameters. 3319 * 3320 * @since 7.0.0 3321 * 3322 * @param BP_Invitation $invite Invitation specified by the $_GET parameters. 3323 */ 3324 return apply_filters( 'bp_get_network_invitation_from_request', $invite ); 3325 } -
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..98500cda6
- + 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_invitations_setup_nav() { 14 if ( ! bp_get_network_invitations_allowed() ) { 15 return; 16 } 17 18 $user_has_access = bp_user_has_access() && bp_user_can( bp_displayed_user_id(), 'bp_network_send_invitation' ); 19 20 /* Add 'Send Invites' to the main user profile navigation */ 21 bp_core_new_nav_item( array( 22 'name' => __( 'Invitations', 'buddypress' ), 23 'slug' => bp_get_members_invitations_slug(), 24 'position' => 80, 25 'screen_function' => 'members_screen_send_invites', 26 'default_subnav_slug' => 'list-invites', 27 'show_for_displayed_user' => $user_has_access 28 ) ); 29 30 $parent_link = trailingslashit( bp_displayed_user_domain() . bp_get_members_invitations_slug() ); 31 32 /* Create two sub nav items for this component */ 33 bp_core_new_subnav_item( array( 34 'name' => __( 'Sent Invites', 'invite-anyone' ), 35 'slug' => 'list-invites', 36 'parent_slug' => bp_get_members_invitations_slug(), 37 'parent_url' => $parent_link, 38 'screen_function' => 'members_screen_list_sent_invites', 39 'position' => 10, 40 'user_has_access' => $user_has_access 41 ) ); 42 43 bp_core_new_subnav_item( array( 44 'name' => __( 'Invite New Members', 'buddypress' ), 45 'slug' => 'send-invites', 46 'parent_slug' => bp_get_members_invitations_slug(), 47 'parent_url' => $parent_link, 48 'screen_function' => 'members_screen_send_invites', 49 'position' => 20, 50 'user_has_access' => $user_has_access && bp_is_my_profile() 51 ) ); 52 } 53 add_action( 'bp_setup_nav', 'bp_invitations_setup_nav' ); 54 55 /** 56 * When a user joins the network via an invitation, skip sending the activation email. 57 * 58 * @param bool $send Whether or not to send the activation key. 59 * @param int $user_id User ID to send activation key to. 60 * @param string $user_email User email to send activation key to. 61 * @param string $activation_key Activation key to be sent. 62 * @param array $usermeta Miscellaneous metadata about the user (blog-specific 63 * signup data, xprofile data, etc). 64 */ 65 function bp_network_invitations_maybe_skip_activation_email( $send, $user_id, $user_email, $activation_key, $usermeta ) { 66 67 $invite = bp_network_get_invites( array( 68 'invitee_email' => $user_email, 69 ) ); 70 71 if ( $invite ) { 72 $send = false; 73 } 74 75 return $send; 76 } 77 add_filter( 'bp_core_signup_send_activation_key', 'bp_network_invitations_maybe_skip_activation_email', 10, 5 ); 78 79 80 /** 81 * When a user joins the network via an invitation: 82 * - mark all invitations and requests as accepted 83 * - activate the user upon signup 84 * 85 * @param bool|WP_Error $user_id True on success, WP_Error on failure. 86 * @param string $user_login Login name requested by the user. 87 * @param string $user_password Password requested by the user. 88 * @param string $user_email Email address requested by the user. 89 */ 90 function bp_network_invitations_complete_signup( $user_id, $user_login, $user_password, $user_email ) { 91 if ( ! $user_id ) { 92 return; 93 } 94 95 // Is this new signup the result of an invitation? 96 $invite = bp_network_get_invites( array( 97 'invitee_email' => $user_email, 98 ) ); 99 100 if ( ! $invite ) { 101 return; 102 } 103 104 $invites_class = new BP_Network_Invitation_Manager(); 105 $args = array( 106 'invitee_email' => $user_email, 107 'item_id' => get_current_network_id(), 108 'type' => 'all' 109 ); 110 $invites_class->mark_accepted( $args ); 111 112 // User has already verified their email by responding to the invitation, so we can activate. 113 $key = bp_get_user_meta( $user_id, 'activation_key', true ); 114 if ( $key ) { 115 /** 116 * Filters the activation signup. 117 * 118 * @since 1.1.0 119 * 120 * @param bool|int $value Value returned by activation. 121 * Integer on success, boolean on failure. 122 */ 123 $user = apply_filters( 'bp_core_activate_account', bp_core_activate_signup( $key ) ); 124 125 // If there were errors, add a message and redirect. 126 if ( ! empty( $user->errors ) ) { 127 bp_core_add_message( $user->get_error_message(), 'error' ); 128 bp_core_redirect( trailingslashit( bp_get_root_domain() . '/' . $bp->pages->activate->slug ) ); 129 } 130 131 bp_core_add_message( __( 'Your account is now active!', 'buddypress' ) ); 132 bp_core_redirect( add_query_arg( 'activated', '1', bp_get_activation_page() ) ); 133 } 134 } 135 add_action( 'bp_core_signup_user', 'bp_network_invitations_complete_signup', 10, 4 ); 136 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..ab4823f11
- + 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 // Trigger a BuddyPress Notification. 30 if ( bp_is_active( 'notifications' ) ) { 31 bp_notifications_add_notification( array( 32 'user_id' => $admin_id, 33 'item_id' => $group_id, 34 'secondary_item_id' => $requesting_user_id, 35 'component_name' => buddypress()->members->id, 36 'component_action' => 'new_membership_request', 37 ) ); 38 } 39 40 // Bail if member opted out of receiving this email. 41 if ( 'no' === bp_get_user_meta( $admin_id, 'notification_network_membership_request', true ) ) { 42 return; 43 } 44 45 $unsubscribe_args = array( 46 'user_id' => $admin_id, 47 'notification_type' => 'network-membership-request', 48 ); 49 50 $request_message = ''; 51 $requests = groups_get_requests( $args = array( 52 'user_id' => $requesting_user_id, 53 'item_id' => $group_id, 54 ) ); 55 if ( $requests ) { 56 $request_message = current( $requests )->content; 57 } 58 59 $group = groups_get_group( $group_id ); 60 $args = array( 61 'tokens' => array( 62 'admin.id' => $admin_id, 63 'group' => $group, 64 'group.name' => $group->name, 65 'group.id' => $group_id, 66 'group-requests.url' => esc_url( bp_get_group_permalink( $group ) . 'admin/membership-requests' ), 67 'profile.url' => esc_url( bp_core_get_user_domain( $requesting_user_id ) ), 68 'requesting-user.id' => $requesting_user_id, 69 'requesting-user.name' => bp_core_get_user_displayname( $requesting_user_id ), 70 'request.message' => $request_message, 71 'unsubscribe' => esc_url( bp_email_get_unsubscribe_link( $unsubscribe_args ) ), 72 ), 73 ); 74 bp_send_email( 'network-membership-request', (int) $admin_id, $args ); 75 } 76 77 /** 78 * Notify member about their group membership request. 79 * 80 * @since 1.0.0 81 * 82 * @param int $requesting_user_id ID of the user requesting group membership. 83 * @param int $group_id ID of the group. 84 * @param bool $accepted Optional. Whether the membership request was accepted. 85 * Default: true. 86 */ 87 function bp_members_membership_request_completed( $requesting_user_id = 0, $group_id = 0, $accepted = true ) { 88 89 // Trigger a BuddyPress Notification. 90 if ( bp_is_active( 'notifications' ) ) { 91 92 // What type of acknowledgement. 93 $type = ! empty( $accepted ) ? 'membership_request_accepted' : 'membership_request_rejected'; 94 95 bp_notifications_add_notification( array( 96 'user_id' => $requesting_user_id, 97 'item_id' => $group_id, 98 'component_name' => buddypress()->groups->id, 99 'component_action' => $type, 100 ) ); 101 } 102 103 // Bail if member opted out of receiving this email. 104 if ( 'no' === bp_get_user_meta( $requesting_user_id, 'notification_membership_request_completed', true ) ) { 105 return; 106 } 107 108 $group = groups_get_group( $group_id ); 109 $args = array( 110 'tokens' => array( 111 'group' => $group, 112 'group.id' => $group_id, 113 'group.name' => $group->name, 114 'group.url' => esc_url( bp_get_group_permalink( $group ) ), 115 'requesting-user.id' => $requesting_user_id, 116 ), 117 ); 118 119 if ( ! empty( $accepted ) ) { 120 121 $unsubscribe_args = array( 122 'user_id' => $requesting_user_id, 123 'notification_type' => 'groups-membership-request-accepted', 124 ); 125 126 $args['tokens']['unsubscribe'] = esc_url( bp_email_get_unsubscribe_link( $unsubscribe_args ) ); 127 128 bp_send_email( 'groups-membership-request-accepted', (int) $requesting_user_id, $args ); 129 130 } else { 131 132 $unsubscribe_args = array( 133 'user_id' => $requesting_user_id, 134 'notification_type' => 'groups-membership-request-rejected', 135 ); 136 137 $args['tokens']['unsubscribe'] = esc_url( bp_email_get_unsubscribe_link( $unsubscribe_args ) ); 138 139 bp_send_email( 'groups-membership-request-rejected', (int) $requesting_user_id, $args ); 140 } 141 } 142 // add_action( 'groups_membership_accepted', 'groups_notification_membership_request_completed', 10, 3 ); 143 // add_action( 'groups_membership_rejected', 'groups_notification_membership_request_completed', 10, 3 ); 144 145 /** Notifications *************************************************************/ 146 147 /** 148 * Format notifications for the Groups component. 149 * 150 * @since 1.0.0 151 * 152 * @param string $action The kind of notification being rendered. 153 * @param int $item_id The primary item ID. 154 * @param int $secondary_item_id The secondary item ID. 155 * @param int $total_items The total number of messaging-related notifications 156 * waiting for the user. 157 * @param string $format 'string' for BuddyBar-compatible notifications; 'array' 158 * for WP Toolbar. Default: 'string'. 159 * @return string 160 */ 161 function bp_members_format_notifications( $action, $item_id, $secondary_item_id, $total_items, $format = 'string' ) { 162 163 switch ( $action ) { 164 case 'new_membership_request': 165 $group_id = $item_id; 166 $requesting_user_id = $secondary_item_id; 167 168 $group = groups_get_group( $group_id ); 169 $group_link = bp_get_group_permalink( $group ); 170 $amount = 'single'; 171 172 // Set up the string and the filter 173 // because different values are passed to the filters, 174 // we'll return values inline. 175 if ( (int) $total_items > 1 ) { 176 $text = sprintf( __( '%1$d new membership requests for the group "%2$s"', 'buddypress' ), (int) $total_items, $group->name ); 177 $amount = 'multiple'; 178 $notification_link = $group_link . 'admin/membership-requests/?n=1'; 179 180 if ( 'string' == $format ) { 181 182 /** 183 * Filters groups multiple new membership request notification for string format. 184 * 185 * This is a dynamic filter that is dependent on item count and action. 186 * Complete filter - bp_groups_multiple_new_membership_requests_notification. 187 * 188 * @since 1.0.0 189 * 190 * @param string $string HTML anchor tag for request. 191 * @param string $group_link The permalink for the group. 192 * @param int $total_items Total number of membership requests. 193 * @param string $group->name Name of the group. 194 * @param string $text Notification content. 195 * @param string $notification_link The permalink for notification. 196 */ 197 return apply_filters( 'bp_groups_' . $amount . '_' . $action . 's_notification', '<a href="' . $notification_link . '">' . $text . '</a>', $group_link, $total_items, $group->name, $text, $notification_link ); 198 } else { 199 200 /** 201 * Filters groups multiple new membership request notification for any non-string format. 202 * 203 * This is a dynamic filter that is dependent on item count and action. 204 * Complete filter - bp_groups_multiple_new_membership_requests_notification. 205 * 206 * @since 1.0.0 207 * 208 * @param array $array Array holding permalink and content for notification. 209 * @param string $group_link The permalink for the group. 210 * @param int $total_items Total number of membership requests. 211 * @param string $group->name Name of the group. 212 * @param string $text Notification content. 213 * @param string $notification_link The permalink for notification. 214 */ 215 return apply_filters( 'bp_groups_' . $amount . '_' . $action . 's_notification', array( 216 'link' => $notification_link, 217 'text' => $text 218 ), $group_link, $total_items, $group->name, $text, $notification_link ); 219 } 220 } else { 221 $user_fullname = bp_core_get_user_displayname( $requesting_user_id ); 222 $text = sprintf( __( '%s requests group membership', 'buddypress' ), $user_fullname ); 223 $notification_link = $group_link . 'admin/membership-requests/?n=1'; 224 225 if ( 'string' == $format ) { 226 227 /** 228 * Filters groups single new membership request notification for string format. 229 * 230 * This is a dynamic filter that is dependent on item count and action. 231 * Complete filter - bp_groups_single_new_membership_request_notification. 232 * 233 * @since 1.0.0 234 * 235 * @param string $string HTML anchor tag for request. 236 * @param string $group_link The permalink for the group. 237 * @param string $user_fullname Full name of requesting user. 238 * @param string $group->name Name of the group. 239 * @param string $text Notification content. 240 * @param string $notification_link The permalink for notification. 241 */ 242 return apply_filters( 'bp_groups_' . $amount . '_' . $action . '_notification', '<a href="' . $notification_link . '">' . $text . '</a>', $group_link, $user_fullname, $group->name, $text, $notification_link ); 243 } else { 244 245 /** 246 * Filters groups single new membership request notification for any non-string format. 247 * 248 * This is a dynamic filter that is dependent on item count and action. 249 * Complete filter - bp_groups_single_new_membership_request_notification. 250 * 251 * @since 1.0.0 252 * 253 * @param array $array Array holding permalink and content for notification. 254 * @param string $group_link The permalink for the group. 255 * @param string $user_fullname Full name of requesting user. 256 * @param string $group->name Name of the group. 257 * @param string $text Notification content. 258 * @param string $notification_link The permalink for notification. 259 */ 260 return apply_filters( 'bp_groups_' . $amount . '_' . $action . '_notification', array( 261 'link' => $notification_link, 262 'text' => $text 263 ), $group_link, $user_fullname, $group->name, $text, $notification_link ); 264 } 265 } 266 267 break; 268 269 case 'membership_request_accepted': 270 $group_id = $item_id; 271 272 $group = groups_get_group( $group_id ); 273 $group_link = bp_get_group_permalink( $group ); 274 $amount = 'single'; 275 276 if ( (int) $total_items > 1 ) { 277 $text = sprintf( __( '%d accepted group membership requests', 'buddypress' ), (int) $total_items, $group->name ); 278 $amount = 'multiple'; 279 $notification_link = trailingslashit( bp_loggedin_user_domain() . bp_get_groups_slug() ) . '?n=1'; 280 281 if ( 'string' == $format ) { 282 283 /** 284 * Filters multiple accepted group membership requests notification for string format. 285 * Complete filter - bp_groups_multiple_membership_request_accepted_notification. 286 * 287 * @since 1.0.0 288 * 289 * @param string $string HTML anchor tag for notification. 290 * @param int $total_items Total number of accepted requests. 291 * @param string $group->name Name of the group. 292 * @param string $text Notification content. 293 * @param string $notification_link The permalink for notification. 294 */ 295 return apply_filters( 'bp_groups_' . $amount . '_' . $action . '_notification', '<a href="' . $notification_link . '">' . $text . '</a>', $total_items, $group->name, $text, $notification_link ); 296 } else { 297 298 /** 299 * Filters multiple accepted group membership requests notification for non-string format. 300 * Complete filter - bp_groups_multiple_membership_request_accepted_notification. 301 * 302 * @since 1.0.0 303 * 304 * @param array $array Array holding permalink and content for notification 305 * @param int $total_items Total number of accepted requests. 306 * @param string $group->name Name of the group. 307 * @param string $text Notification content. 308 * @param string $notification_link The permalink for notification. 309 */ 310 return apply_filters( 'bp_groups_' . $amount . '_' . $action . '_notification', array( 311 'link' => $notification_link, 312 'text' => $text 313 ), $total_items, $group->name, $text, $notification_link ); 314 } 315 } else { 316 $text = sprintf( __( 'Membership for group "%s" accepted', 'buddypress' ), $group->name ); 317 $filter = 'bp_groups_single_membership_request_accepted_notification'; 318 $notification_link = $group_link . '?n=1'; 319 320 if ( 'string' == $format ) { 321 322 /** 323 * Filters single accepted group membership request notification for string format. 324 * Complete filter - bp_groups_single_membership_request_accepted_notification. 325 * 326 * @since 1.0.0 327 * 328 * @param string $string HTML anchor tag for notification. 329 * @param string $group_link The permalink for the group. 330 * @param string $group->name Name of the group. 331 * @param string $text Notification content. 332 * @param string $notification_link The permalink for notification. 333 */ 334 return apply_filters( 'bp_groups_' . $amount . '_' . $action . '_notification', '<a href="' . $notification_link . '">' . $text . '</a>', $group_link, $group->name, $text, $notification_link ); 335 } else { 336 337 /** 338 * Filters single accepted group membership request notification for non-string format. 339 * Complete filter - bp_groups_single_membership_request_accepted_notification. 340 * 341 * @since 1.0.0 342 * 343 * @param array $array Array holding permalink and content for notification. 344 * @param string $group_link The permalink for the group. 345 * @param string $group->name Name of the group. 346 * @param string $text Notification content. 347 * @param string $notification_link The permalink for notification. 348 */ 349 return apply_filters( $filter, array( 350 'link' => $notification_link, 351 'text' => $text 352 ), $group_link, $group->name, $text, $notification_link ); 353 } 354 } 355 356 break; 357 358 case 'membership_request_rejected': 359 $group_id = $item_id; 360 361 $group = groups_get_group( $group_id ); 362 $group_link = bp_get_group_permalink( $group ); 363 $amount = 'single'; 364 365 if ( (int) $total_items > 1 ) { 366 $text = sprintf( __( '%d rejected group membership requests', 'buddypress' ), (int) $total_items, $group->name ); 367 $amount = 'multiple'; 368 $notification_link = trailingslashit( bp_loggedin_user_domain() . bp_get_groups_slug() ) . '?n=1'; 369 370 if ( 'string' == $format ) { 371 372 /** 373 * Filters multiple rejected group membership requests notification for string format. 374 * Complete filter - bp_groups_multiple_membership_request_rejected_notification. 375 * 376 * @since 1.0.0 377 * 378 * @param string $string HTML anchor tag for notification. 379 * @param int $total_items Total number of rejected requests. 380 * @param string $group->name Name of the group. 381 * @param string $text Notification content. 382 * @param string $notification_link The permalink for notification. 383 */ 384 return apply_filters( 'bp_groups_' . $amount . '_' . $action . '_notification', '<a href="' . $notification_link . '">' . $text . '</a>', $total_items, $group->name ); 385 } else { 386 387 /** 388 * Filters multiple rejected group membership requests notification for non-string format. 389 * Complete filter - bp_groups_multiple_membership_request_rejected_notification. 390 * 391 * @since 1.0.0 392 * 393 * @param array $array Array holding permalink and content for notification. 394 * @param int $total_items Total number of rejected requests. 395 * @param string $group->name Name of the group. 396 * @param string $text Notification content. 397 * @param string $notification_link The permalink for notification. 398 */ 399 return apply_filters( 'bp_groups_' . $amount . '_' . $action . '_notification', array( 400 'link' => $notification_link, 401 'text' => $text 402 ), $total_items, $group->name, $text, $notification_link ); 403 } 404 } else { 405 $text = sprintf( __( 'Membership for group "%s" rejected', 'buddypress' ), $group->name ); 406 $notification_link = $group_link . '?n=1'; 407 408 if ( 'string' == $format ) { 409 410 /** 411 * Filters single rejected group membership requests notification for string format. 412 * Complete filter - bp_groups_single_membership_request_rejected_notification. 413 * 414 * @since 1.0.0 415 * 416 * @param string $string HTML anchor tag for notification. 417 * @param int $group_link The permalink for the group. 418 * @param string $group->name Name of the group. 419 * @param string $text Notification content. 420 * @param string $notification_link The permalink for notification. 421 */ 422 return apply_filters( 'bp_groups_' . $amount . '_' . $action . '_notification', '<a href="' . $notification_link . '">' . $text . '</a>', $group_link, $group->name, $text, $notification_link ); 423 } else { 424 425 /** 426 * Filters single rejected group membership requests notification for non-string format. 427 * Complete filter - bp_groups_single_membership_request_rejected_notification. 428 * 429 * @since 1.0.0 430 * 431 * @param array $array Array holding permalink and content for notification. 432 * @param int $group_link The permalink for the group. 433 * @param string $group->name Name of the group. 434 * @param string $text Notification content. 435 * @param string $notification_link The permalink for notification. 436 */ 437 return apply_filters( 'bp_groups_' . $amount . '_' . $action . '_notification', array( 438 'link' => $notification_link, 439 'text' => $text 440 ), $group_link, $group->name, $text, $notification_link ); 441 } 442 } 443 444 break; 445 446 case 'member_promoted_to_admin': 447 $group_id = $item_id; 448 449 $group = groups_get_group( $group_id ); 450 $group_link = bp_get_group_permalink( $group ); 451 $amount = 'single'; 452 453 if ( (int) $total_items > 1 ) { 454 $text = sprintf( __( 'You were promoted to an admin in %d groups', 'buddypress' ), (int) $total_items ); 455 $amount = 'multiple'; 456 $notification_link = trailingslashit( bp_loggedin_user_domain() . bp_get_groups_slug() ) . '?n=1'; 457 458 if ( 'string' == $format ) { 459 /** 460 * Filters multiple promoted to group admin notification for string format. 461 * Complete filter - bp_groups_multiple_member_promoted_to_admin_notification. 462 * 463 * @since 1.0.0 464 * 465 * @param string $string HTML anchor tag for notification. 466 * @param int $total_items Total number of rejected requests. 467 * @param string $text Notification content. 468 * @param string $notification_link The permalink for notification. 469 */ 470 return apply_filters( 'bp_groups_' . $amount . '_' . $action . '_notification', '<a href="' . $notification_link . '">' . $text . '</a>', $total_items, $text, $notification_link ); 471 } else { 472 /** 473 * Filters multiple promoted to group admin notification for non-string format. 474 * Complete filter - bp_groups_multiple_member_promoted_to_admin_notification. 475 * 476 * @since 1.0.0 477 * 478 * @param array $array Array holding permalink and content for notification. 479 * @param int $total_items Total number of rejected requests. 480 * @param string $text Notification content. 481 * @param string $notification_link The permalink for notification. 482 */ 483 return apply_filters( 'bp_groups_' . $amount . '_' . $action . '_notification', array( 484 'link' => $notification_link, 485 'text' => $text 486 ), $total_items, $text, $notification_link ); 487 } 488 } else { 489 $text = sprintf( __( 'You were promoted to an admin in the group "%s"', 'buddypress' ), $group->name ); 490 $notification_link = $group_link . '?n=1'; 491 492 if ( 'string' == $format ) { 493 /** 494 * Filters single promoted to group admin notification for non-string format. 495 * Complete filter - bp_groups_single_member_promoted_to_admin_notification. 496 * 497 * @since 1.0.0 498 * 499 * @param string $string HTML anchor tag for notification. 500 * @param int $group_link The permalink for the group. 501 * @param string $group->name Name of the group. 502 * @param string $text Notification content. 503 * @param string $notification_link The permalink for notification. 504 */ 505 return apply_filters( 'bp_groups_' . $amount . '_' . $action . '_notification', '<a href="' . $notification_link . '">' . $text . '</a>', $group_link, $group->name, $text, $notification_link ); 506 } else { 507 /** 508 * Filters single promoted to group admin notification for non-string format. 509 * Complete filter - bp_groups_single_member_promoted_to_admin_notification. 510 * 511 * @since 1.0.0 512 * 513 * @param array $array Array holding permalink and content for notification. 514 * @param int $group_link The permalink for the group. 515 * @param string $group->name Name of the group. 516 * @param string $text Notification content. 517 * @param string $notification_link The permalink for notification. 518 */ 519 return apply_filters( 'bp_groups_' . $amount . '_' . $action . '_notification', array( 520 'link' => $notification_link, 521 'text' => $text 522 ), $group_link, $group->name, $text, $notification_link ); 523 } 524 } 525 526 break; 527 528 case 'member_promoted_to_mod': 529 $group_id = $item_id; 530 531 $group = groups_get_group( $group_id ); 532 $group_link = bp_get_group_permalink( $group ); 533 $amount = 'single'; 534 535 if ( (int) $total_items > 1 ) { 536 $text = sprintf( __( 'You were promoted to a mod in %d groups', 'buddypress' ), (int) $total_items ); 537 $amount = 'multiple'; 538 $notification_link = trailingslashit( bp_loggedin_user_domain() . bp_get_groups_slug() ) . '?n=1'; 539 540 if ( 'string' == $format ) { 541 /** 542 * Filters multiple promoted to group mod notification for string format. 543 * Complete filter - bp_groups_multiple_member_promoted_to_mod_notification. 544 * 545 * @since 1.0.0 546 * 547 * @param string $string HTML anchor tag for notification. 548 * @param int $total_items Total number of rejected requests. 549 * @param string $text Notification content. 550 * @param string $notification_link The permalink for notification. 551 */ 552 return apply_filters( 'bp_groups_' . $amount . '_' . $action . '_notification', '<a href="' . $notification_link . '">' . $text . '</a>', $total_items, $text, $notification_link ); 553 } else { 554 /** 555 * Filters multiple promoted to group mod notification for non-string format. 556 * Complete filter - bp_groups_multiple_member_promoted_to_mod_notification. 557 * 558 * @since 1.0.0 559 * 560 * @param array $array Array holding permalink and content for notification. 561 * @param int $total_items Total number of rejected requests. 562 * @param string $text Notification content. 563 * @param string $notification_link The permalink for notification. 564 */ 565 return apply_filters( 'bp_groups_' . $amount . '_' . $action . '_notification', array( 566 'link' => $notification_link, 567 'text' => $text 568 ), $total_items, $text, $notification_link ); 569 } 570 } else { 571 $text = sprintf( __( 'You were promoted to a mod in the group "%s"', 'buddypress' ), $group->name ); 572 $notification_link = $group_link . '?n=1'; 573 574 if ( 'string' == $format ) { 575 /** 576 * Filters single promoted to group mod notification for string format. 577 * Complete filter - bp_groups_single_member_promoted_to_mod_notification. 578 * 579 * @since 1.0.0 580 * 581 * @param string $string HTML anchor tag for notification. 582 * @param int $group_link The permalink for the group. 583 * @param string $group->name Name of the group. 584 * @param string $text Notification content. 585 * @param string $notification_link The permalink for notification. 586 */ 587 return apply_filters( 'bp_groups_' . $amount . '_' . $action . '_notification', '<a href="' . $notification_link . '">' . $text . '</a>', $group_link, $group->name, $text, $notification_link ); 588 } else { 589 /** 590 * Filters single promoted to group admin notification for non-string format. 591 * Complete filter - bp_groups_single_member_promoted_to_mod_notification. 592 * 593 * @since 1.0.0 594 * 595 * @param array $array Array holding permalink and content for notification. 596 * @param int $group_link The permalink for the group. 597 * @param string $group->name Name of the group. 598 * @param string $text Notification content. 599 * @param string $notification_link The permalink for notification. 600 */ 601 return apply_filters( 'bp_groups_' . $amount . '_' . $action . '_notification', array( 602 'link' => $notification_link, 603 'text' => $text 604 ), $group_link, $group->name, $text, $notification_link ); 605 } 606 } 607 608 break; 609 610 case 'group_invite': 611 $group_id = $item_id; 612 $group = groups_get_group( $group_id ); 613 $group_link = bp_get_group_permalink( $group ); 614 $amount = 'single'; 615 616 $notification_link = bp_loggedin_user_domain() . bp_get_groups_slug() . '/invites/?n=1'; 617 618 if ( (int) $total_items > 1 ) { 619 $text = sprintf( __( 'You have %d new group invitations', 'buddypress' ), (int) $total_items ); 620 $amount = 'multiple'; 621 622 if ( 'string' == $format ) { 623 /** 624 * Filters multiple group invitation notification for string format. 625 * Complete filter - bp_groups_multiple_group_invite_notification. 626 * 627 * @since 1.0.0 628 * 629 * @param string $string HTML anchor tag for notification. 630 * @param int $total_items Total number of rejected requests. 631 * @param string $text Notification content. 632 * @param string $notification_link The permalink for notification. 633 */ 634 return apply_filters( 'bp_groups_' . $amount . '_' . $action . '_notification', '<a href="' . $notification_link . '">' . $text . '</a>', $total_items, $text, $notification_link ); 635 } else { 636 /** 637 * Filters multiple group invitation notification for non-string format. 638 * Complete filter - bp_groups_multiple_group_invite_notification. 639 * 640 * @since 1.0.0 641 * 642 * @param array $array Array holding permalink and content for notification. 643 * @param int $total_items Total number of rejected requests. 644 * @param string $text Notification content. 645 * @param string $notification_link The permalink for notification. 646 */ 647 return apply_filters( 'bp_groups_' . $amount . '_' . $action . '_notification', array( 648 'link' => $notification_link, 649 'text' => $text 650 ), $total_items, $text, $notification_link ); 651 } 652 } else { 653 $text = sprintf( __( 'You have an invitation to the group: %s', 'buddypress' ), $group->name ); 654 $filter = 'bp_groups_single_group_invite_notification'; 655 656 if ( 'string' == $format ) { 657 /** 658 * Filters single group invitation notification for string format. 659 * Complete filter - bp_groups_single_group_invite_notification. 660 * 661 * @since 1.0.0 662 * 663 * @param string $string HTML anchor tag for notification. 664 * @param int $group_link The permalink for the group. 665 * @param string $group->name Name of the group. 666 * @param string $text Notification content. 667 * @param string $notification_link The permalink for notification. 668 */ 669 return apply_filters( 'bp_groups_' . $amount . '_' . $action . '_notification', '<a href="' . $notification_link . '">' . $text . '</a>', $group_link, $group->name, $text, $notification_link ); 670 } else { 671 /** 672 * Filters single group invitation notification for non-string format. 673 * Complete filter - bp_groups_single_group_invite_notification. 674 * 675 * @since 1.0.0 676 * 677 * @param array $array Array holding permalink and content for notification. 678 * @param int $group_link The permalink for the group. 679 * @param string $group->name Name of the group. 680 * @param string $text Notification content. 681 * @param string $notification_link The permalink for notification. 682 */ 683 return apply_filters( 'bp_groups_' . $amount . '_' . $action . '_notification', array( 684 'link' => $notification_link, 685 'text' => $text 686 ), $group_link, $group->name, $text, $notification_link ); 687 } 688 } 689 690 break; 691 692 default: 693 694 /** 695 * Filters plugin-added group-related custom component_actions. 696 * 697 * @since 2.4.0 698 * 699 * @param string $notification Null value. 700 * @param int $item_id The primary item ID. 701 * @param int $secondary_item_id The secondary item ID. 702 * @param int $total_items The total number of messaging-related notifications 703 * waiting for the user. 704 * @param string $format 'string' for BuddyBar-compatible notifications; 705 * 'array' for WP Toolbar. 706 */ 707 $custom_action_notification = apply_filters( 'bp_groups_' . $action . '_notification', null, $item_id, $secondary_item_id, $total_items, $format ); 708 709 if ( ! is_null( $custom_action_notification ) ) { 710 return $custom_action_notification; 711 } 712 713 break; 714 } 715 716 /** 717 * Fires right before returning the formatted group notifications. 718 * 719 * @since 1.0.0 720 * 721 * @param string $action The type of notification being rendered. 722 * @param int $item_id The primary item ID. 723 * @param int $secondary_item_id The secondary item ID. 724 * @param int $total_items Total amount of items to format. 725 */ 726 do_action( 'groups_format_notifications', $action, $item_id, $secondary_item_id, $total_items ); 727 728 return false; 729 } 730 731 /** 732 * Mark notifications read when a member's group membership request is granted. 733 * 734 * @since 2.8.0 735 * 736 * @param int $user_id ID of the user. 737 * @param int $group_id ID of the group. 738 */ 739 function bp_members_accept_request_mark_notifications( $user_id, $group_id ) { 740 if ( bp_is_active( 'notifications' ) ) { 741 // First null parameter marks read for all admins. 742 bp_notifications_mark_notifications_by_item_id( null, $group_id, buddypress()->groups->id, 'new_membership_request', $user_id ); 743 } 744 } 745 // add_action( 'groups_membership_accepted', 'bp_groups_accept_request_mark_notifications', 10, 2 ); 746 // add_action( 'groups_membership_rejected', 'bp_groups_accept_request_mark_notifications', 10, 2 ); 747 748 /** 749 * Render the group settings fields on the Notification Settings page. 750 * 751 * @since 6.0.0 752 */ 753 function bp_members_screen_notification_settings() { 754 755 if ( ! bp_user_can( bp_displayed_user_id(), 'manage_network_membership_requests' ) ) { 756 return; 757 } 758 759 if ( ! $network_membership_request = bp_get_user_meta( bp_displayed_user_id(), 'notification_network_membership_request', true ) ) { 760 $network_membership_request = 'yes'; 761 } 762 763 ?> 764 765 <table class="notification-settings" id="bp-members-notification-settings"> 766 <thead> 767 <tr> 768 <th class="icon"></th> 769 <th class="title"><?php _ex( 'Members', 'Member component settings on notification settings page', 'buddypress' ) ?></th> 770 <th class="yes"><?php _e( 'Yes', 'buddypress' ) ?></th> 771 <th class="no"><?php _e( 'No', 'buddypress' )?></th> 772 </tr> 773 </thead> 774 775 <tbody> 776 <tr id="bp-members-notification-settings-invitation"> 777 <td></td> 778 <td><?php _ex( 'A user requests membership on this network', 'Member component settings on notification settings page','buddypress' ) ?></td> 779 <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 780 /* translators: accessibility text */ 781 _e( 'Yes, send email', 'buddypress' ); 782 ?></label></td> 783 <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 784 /* translators: accessibility text */ 785 _e( 'No, do not send email', 'buddypress' ); 786 ?></label></td> 787 </tr> 788 789 <?php 790 791 /** 792 * Fires at the end of the available group settings fields on Notification Settings page. 793 * 794 * @since 6.0.0 795 */ 796 do_action( 'bp_members_screen_notification_settings' ); ?> 797 798 </tbody> 799 </table> 800 801 <?php 802 } 803 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 551718644..82f34f86a 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 1.5.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 1.5.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 1.5.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() { 2208 2236 */ 2209 2237 function bp_get_signup_email_value() { 2210 2238 $value = ''; 2211 if ( isset( $_POST['signup_email'] ) ) 2239 if ( isset( $_POST['signup_email'] ) ) { 2212 2240 $value = $_POST['signup_email']; 2241 } else if ( bp_get_network_invitations_allowed() ) { 2242 $invite = bp_get_network_invitation_from_request(); 2243 if ( $invite ) { 2244 $value = $invite->invitee_email; 2245 } 2246 } 2213 2247 2214 2248 /** 2215 2249 * Filters the email address submitted during signup. … … function bp_signup_allowed() { 2582 2616 return apply_filters( 'bp_get_signup_allowed', (bool) bp_get_option( 'users_can_register' ) ); 2583 2617 } 2584 2618 2619 /** 2620 * Are users allowed to invite users to join this site? 2621 * 2622 * @since 7.0.0 2623 * 2624 * @return bool 2625 */ 2626 function bp_get_network_invitations_allowed() { 2627 /** 2628 * Filters whether or not network invitations are allowed. 2629 * 2630 * @since 7.0.0 2631 * 2632 * @param bool $allowed Whether or not network invitations are allowed. 2633 */ 2634 return apply_filters( 'bp_get_network_invitations_allowed', (bool) bp_get_option( 'bp-enable-network-invitations' ) ); 2635 } 2636 2585 2637 /** 2586 2638 * Hook member activity feed to <head>. 2587 2639 * … … function bp_avatar_delete_link() { 2688 2740 */ 2689 2741 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' ) ); 2690 2742 } 2743 2744 2745 /** The Network Invitations Loop ******************************************************************/ 2746 2747 /** 2748 * Initialize the network invitations loop. 2749 * 2750 * Based on the $args passed, bp_has_invitations() populates 2751 * buddypress()->invitations->query_loop global, enabling the use of BP 2752 * templates and template functions to display a list of invitations. 2753 * 2754 * @since 1.9.0 2755 * 2756 * @param array|string $args { 2757 * Arguments for limiting the contents of the invitations loop. Can be 2758 * passed as an associative array, or as a URL query string. 2759 * 2760 * See {@link BP_Invitations_Invitation::get()} for detailed 2761 * information on the arguments. In addition, also supports: 2762 * 2763 * @type int $max Optional. Max items to display. Default: false. 2764 * @type string $page_arg URL argument to use for pagination. 2765 * Default: 'ipage'. 2766 * } 2767 * @return bool 2768 */ 2769 function bp_has_network_invitations( $args = '' ) { 2770 2771 // Get the user ID. 2772 if ( bp_displayed_user_id() ) { 2773 $user_id = bp_displayed_user_id(); 2774 } else { 2775 $user_id = bp_loggedin_user_id(); 2776 } 2777 2778 // Set the search terms (by default an empty string to get all notifications) 2779 $search_terms = ''; 2780 2781 if ( isset( $_REQUEST['s'] ) ) { 2782 $search_terms = stripslashes( $_REQUEST['s'] ); 2783 } 2784 2785 // Parse the args. 2786 $r = bp_parse_args( $args, array( 2787 'id' => false, 2788 'inviter_id' => $user_id, 2789 'invitee_email' => false, 2790 'item_id' => false, 2791 'type' => 'invite', 2792 'invite_sent' => 'all', 2793 'accepted' => 'pending', 2794 'search_terms' => $search_terms, 2795 'order_by' => 'date_modified', 2796 'sort_order' => 'DESC', 2797 'page' => 1, 2798 'per_page' => 25, 2799 'fields' => 'all', 2800 2801 // These are additional arguments that are not available in 2802 // BP_Invitations_Invitation::get(). 2803 'page_arg' => 'ipage', 2804 ), 'has_network_invitations' ); 2805 2806 // Get the notifications. 2807 $query_loop = new BP_Network_Invitations_Template( $r ); 2808 2809 // Setup the global query loop. 2810 buddypress()->network_invitations->query_loop = $query_loop; 2811 2812 /** 2813 * Filters whether or not the user has network invitations to display. 2814 * 2815 * @since 1.9.0 2816 * @since 2.6.0 Added the `$r` parameter. 2817 * 2818 * @param bool $value Whether or not there are network invitations to display. 2819 * @param BP_Notifications_Template $query_loop BP_Network_Invitations_Template object instance. 2820 * @param array $r Array of arguments passed into the BP_Network_Invitations_Template class. 2821 */ 2822 return apply_filters( 'bp_has_network_invitations', $query_loop->has_invitations(), $query_loop, $r ); 2823 } 2824 2825 /** 2826 * Get the network invitations returned by the template loop. 2827 * 2828 * @since 1.9.0 2829 * 2830 * @return array List of network invitations. 2831 */ 2832 function bp_the_network_invitations() { 2833 return buddypress()->network_invitations->query_loop->invitations(); 2834 } 2835 2836 /** 2837 * Get the current network invitation object in the loop. 2838 * 2839 * @since 7.0.0 2840 * 2841 * @return object The current network invitation within the loop. 2842 */ 2843 function bp_the_network_invitation() { 2844 return buddypress()->network_invitations->query_loop->the_invitation(); 2845 } 2846 2847 /** 2848 * Output the pagination count for the current network invitations loop. 2849 * 2850 * @since 7.0.0 2851 */ 2852 function bp_network_invitations_pagination_count() { 2853 echo bp_get_network_invitations_pagination_count(); 2854 } 2855 /** 2856 * Return the pagination count for the current network invitation loop. 2857 * 2858 * @since 7.0.0 2859 * 2860 * @return string HTML for the pagination count. 2861 */ 2862 function bp_get_network_invitations_pagination_count() { 2863 $query_loop = buddypress()->network_invitations->query_loop; 2864 $start_num = intval( ( $query_loop->pag_page - 1 ) * $query_loop->pag_num ) + 1; 2865 $from_num = bp_core_number_format( $start_num ); 2866 $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 ) ); 2867 $total = bp_core_number_format( $query_loop->total_invitation_count ); 2868 2869 if ( 1 == $query_loop->total_invitation_count ) { 2870 $pag = __( 'Viewing 1 invitation', 'buddypress' ); 2871 } else { 2872 /* translators: 1: notification from number. 2: notification to number. 3: total notifications. */ 2873 $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 ); 2874 } 2875 2876 /** 2877 * Filters the pagination count for the current network invitation loop. 2878 * 2879 * @since 1.9.0 2880 * 2881 * @param string $pag HTML for the pagination count. 2882 */ 2883 return apply_filters( 'bp_network_invitations_pagination_count', $pag ); 2884 } 2885 2886 /** 2887 * Output the pagination links for the current network invitation loop. 2888 * 2889 * @since 7.0.0 2890 */ 2891 function bp_network_invitations_pagination_links() { 2892 echo bp_get_network_invitations_pagination_links(); 2893 } 2894 /** 2895 * Return the pagination links for the current network invitations loop. 2896 * 2897 * @since 1.9.0 2898 * 2899 * @return string HTML for the pagination links. 2900 */ 2901 function bp_get_network_invitations_pagination_links() { 2902 2903 /** 2904 * Filters the pagination links for the current network invitations loop. 2905 * 2906 * @since 1.9.0 2907 * 2908 * @param string $pag_links HTML for the pagination links. 2909 */ 2910 return apply_filters( 'bp_get_network_invitations_pagination_links', buddypress()->network_invitations->query_loop->pag_links ); 2911 } 2912 2913 /** 2914 * Output the ID of the invitation currently being iterated on. 2915 * 2916 * @since 7.0.0 2917 */ 2918 function bp_the_network_invitation_property( $property ) { 2919 echo bp_get_the_network_invitation_property( $property ); 2920 } 2921 /** 2922 * Return the value for a property of the network invitation currently being iterated on. 2923 * 2924 * @since 7.0.0 2925 * 2926 * @return int ID of the current network invitation. 2927 */ 2928 function bp_get_the_network_invitation_property( $property = 'id' ) { 2929 2930 switch ( $property ) { 2931 case 'id': 2932 case 'user_id': 2933 case 'item_id': 2934 case 'secondary_item_id': 2935 case 'invite_sent': 2936 case 'accepted': 2937 $value = 0; 2938 break; 2939 case 'invitee_email': 2940 case 'type': 2941 case 'content': 2942 case 'date_modified': 2943 $value = ''; 2944 break; 2945 default: 2946 // A known property has not been specified. 2947 $property = null; 2948 $value = ''; 2949 break; 2950 } 2951 2952 if ( isset( buddypress()->network_invitations->query_loop->invitation->{$property} ) ) { 2953 $value = buddypress()->network_invitations->query_loop->invitation->{$property}; 2954 } 2955 2956 /** 2957 * Filters the property of the network invitation currently being iterated on. 2958 * 2959 * @since 7.0.0 2960 * 2961 * @param int|string $value Property value of the network invitation being iterated on. 2962 */ 2963 return apply_filters( 'bp_get_the_network_invitation_property_' . $property, $value ); 2964 } 2965 2966 /** 2967 * Output the action links for the current invitation. 2968 * 2969 * @since 7.0.0 2970 * 2971 * @param array|string $args Array of arguments. 2972 */ 2973 function bp_the_network_invitation_action_links( $args = '' ) { 2974 echo bp_get_the_network_invitation_action_links( $args ); 2975 } 2976 /** 2977 * Return the action links for the current notification. 2978 * 2979 * @since 7.0.0 2980 * 2981 * @param array|string $args { 2982 * @type string $before HTML before the links. 2983 * @type string $after HTML after the links. 2984 * @type string $sep HTML between the links. 2985 * @type array $links Array of links to implode by 'sep'. 2986 * @type int $user_id User ID to fetch action links for. Defaults to displayed user ID. 2987 * } 2988 * @return string HTML links for actions to take on single notifications. 2989 */ 2990 function bp_get_the_network_invitation_action_links( $args = '' ) { 2991 // Set default user ID to use. 2992 $inviter_id = isset( $args['inviter_id'] ) ? $args['inviter_id'] : bp_displayed_user_id(); 2993 2994 // Parse. 2995 $r = wp_parse_args( $args, array( 2996 'before' => '', 2997 'after' => '', 2998 'sep' => ' | ', 2999 'links' => array( 3000 bp_get_the_network_invitation_resend_link( $inviter_id ), 3001 bp_get_the_network_invitation_delete_link( $inviter_id ) 3002 ) 3003 ) ); 3004 3005 // Build the links. 3006 $retval = $r['before'] . implode( $r['sep'], $r['links'] ) . $r['after']; 3007 3008 /** 3009 * Filters the action links for the current notification. 3010 * 3011 * @since 1.9.0 3012 * @since 2.6.0 Added the `$r` parameter. 3013 * 3014 * @param string $retval HTML links for actions to take on single notifications. 3015 * @param array $r Array of parsed arguments. 3016 */ 3017 return apply_filters( 'bp_get_the_network_invitation_action_links', $retval, $r ); 3018 } 3019 3020 /** 3021 * Output the resend link for the current invitation. 3022 * 3023 * @since 7.0.0 3024 * 3025 * @param int $user_id The user ID. 3026 */ 3027 function bp_the_network_invitation_resend_link( $user_id = 0 ) { 3028 echo bp_get_the_network_invitation_delete_link( $user_id ); 3029 } 3030 /** 3031 * Return the resend link for the current notification. 3032 * 3033 * @since 7.0.0 3034 * 3035 * @param int $user_id The user ID. 3036 * @return string 3037 */ 3038 function bp_get_the_network_invitation_resend_link( $user_id = 0 ) { 3039 // Set default user ID to use. 3040 $user_id = 0 === $user_id ? bp_displayed_user_id() : $user_id; 3041 3042 // Don't allow resending of accepted invitations. 3043 if ( bp_get_the_network_invitation_property( 'accepted' ) ) { 3044 return; 3045 } 3046 3047 $retval = sprintf( '<a href="%1$s" class="resend secondary confirm bp-tooltip">%2$s</a>', esc_url( bp_get_the_network_invitation_resend_url( $user_id ) ), __( 'Resend', 'buddypress' ) ); 3048 3049 /** 3050 * Filters the resend link for the current invitation. 3051 * 3052 * @since 7.0.0 3053 * 3054 * @param string $retval HTML for the delete link for the current notification. 3055 * @param int $user_id The user ID. 3056 */ 3057 return apply_filters( 'bp_get_the_network_invitation_resend_link', $retval, $user_id ); 3058 } 3059 3060 /** 3061 * Output the URL used for resending a single invitation. 3062 * 3063 * Since this function directly outputs a URL, it is escaped. 3064 * 3065 * @since 7.0.0 3066 * 3067 * @param int $user_id The user ID. 3068 */ 3069 function bp_the_network_invitation_resend_url( $user_id = 0 ) { 3070 echo esc_url( bp_get_the_network_invitation_resend_url( $user_id ) ); 3071 } 3072 /** 3073 * Return the URL used for resending a single invitation. 3074 * 3075 * @since 7.0.0 3076 * 3077 * @param int $user_id The user ID. 3078 * @return string 3079 */ 3080 function bp_get_the_network_invitation_resend_url( $user_id = 0 ) { 3081 // Set default user ID to use. 3082 $user_id = 0 === $user_id ? bp_displayed_user_id() : $user_id; 3083 $link = bp_get_network_invitations_list_invites_permalink( $user_id ); 3084 3085 // Get the ID. 3086 $id = bp_get_the_network_invitation_property( 'id' ); 3087 3088 // Get the args to add to the URL. 3089 $args = array( 3090 'action' => 'resend', 3091 'invitation_id' => $id 3092 ); 3093 3094 // Add the args. 3095 $url = add_query_arg( $args, $link ); 3096 3097 // Add the nonce. 3098 $url = wp_nonce_url( $url, 'bp_network_invitation_resend_' . $id ); 3099 3100 /** 3101 * Filters the URL used for resending a single invitation. 3102 * 3103 * @since 7.0.0 3104 * 3105 * @param string $url URL used for deleting a single invitation. 3106 * @param int $user_id The user ID. 3107 */ 3108 return apply_filters( 'bp_get_the_network_invitation_resend_url', $url, $user_id ); 3109 } 3110 3111 /** 3112 * Output the delete link for the current invitation. 3113 * 3114 * @since 7.0.0 3115 * 3116 * @param int $user_id The user ID. 3117 */ 3118 function bp_the_network_invitation_delete_link( $user_id = 0 ) { 3119 echo bp_get_the_network_invitation_delete_link( $user_id ); 3120 } 3121 /** 3122 * Return the delete link for the current invitation. 3123 * 3124 * @since 7.0.0 3125 * 3126 * @param int $user_id The user ID. 3127 * @return string 3128 */ 3129 function bp_get_the_network_invitation_delete_link( $user_id = 0 ) { 3130 // Set default user ID to use. 3131 $user_id = 0 === $user_id ? bp_displayed_user_id() : $user_id; 3132 3133 // Modify the message for accepted/not accepted invitatons. 3134 if ( bp_get_the_network_invitation_property( 'accepted' ) ) { 3135 $message = __( 'Delete', 'buddypress' ); 3136 } else { 3137 $message = __( 'Cancel', 'buddypress' ); 3138 } 3139 3140 $retval = sprintf( '<a href="%1$s" class="delete secondary confirm bp-tooltip">%2$s</a>', esc_url( bp_get_the_network_invitation_delete_url( $user_id ) ), $message ); 3141 3142 /** 3143 * Filters the delete link for the current invitation. 3144 * 3145 * @since 7.0.0 3146 * 3147 * @param string $retval HTML for the delete link for the current notification. 3148 * @param int $user_id The user ID. 3149 */ 3150 return apply_filters( 'bp_get_the_network_invitation_delete_link', $retval, $user_id ); 3151 } 3152 3153 /** 3154 * Output the URL used for deleting a single invitation. 3155 * 3156 * Since this function directly outputs a URL, it is escaped. 3157 * 3158 * @since 7.0.0 3159 * 3160 * @param int $user_id The user ID. 3161 */ 3162 function bp_the_network_invitation_delete_url( $user_id = 0 ) { 3163 echo esc_url( bp_get_the_network_invitation_delete_url( $user_id ) ); 3164 } 3165 /** 3166 * Return the URL used for deleting a single invitation. 3167 * 3168 * @since 7.0.0 3169 * 3170 * @param int $user_id The user ID. 3171 * @return string 3172 */ 3173 function bp_get_the_network_invitation_delete_url( $user_id = 0 ) { 3174 // Set default user ID to use. 3175 $user_id = 0 === $user_id ? bp_displayed_user_id() : $user_id; 3176 $link = bp_get_network_invitations_list_invites_permalink( $user_id ); 3177 3178 // Get the ID. 3179 $id = bp_get_the_network_invitation_property( 'id' ); 3180 3181 // Get the args to add to the URL. 3182 $args = array( 3183 'action' => 'cancel', 3184 'invitation_id' => $id 3185 ); 3186 3187 // Add the args. 3188 $url = add_query_arg( $args, $link ); 3189 3190 // Add the nonce. 3191 $url = wp_nonce_url( $url, 'bp_network_invitation_cancel_' . $id ); 3192 3193 /** 3194 * Filters the URL used for deleting a single invitation. 3195 * 3196 * @since 7.0.0 3197 * 3198 * @param string $url URL used for deleting a single invitation. 3199 * @param int $user_id The user ID. 3200 */ 3201 return apply_filters( 'bp_get_the_network_invitation_delete_url', $url, $user_id ); 3202 } 3203 3204 /** 3205 * Output the read notifications permalink for a user. 3206 * 3207 * @since 7.0.0 3208 * 3209 * @param int $user_id The user ID. 3210 */ 3211 function bp_network_invitations_list_invites_permalink( $user_id = 0 ) { 3212 echo bp_get_network_invitations_list_invites_permalink( $user_id ); 3213 } 3214 /** 3215 * Return the read notifications permalink. 3216 * 3217 * @since 7.0.0 3218 * 3219 * @return string Read notifications permalink. 3220 */ 3221 function bp_get_network_invitations_list_invites_permalink( $user_id = 0 ) { 3222 if ( 0 === $user_id ) { 3223 $user_id = bp_loggedin_user_id(); 3224 $domain = bp_loggedin_user_domain(); 3225 } else { 3226 $domain = bp_core_get_user_domain( (int) $user_id ); 3227 } 3228 3229 $retval = trailingslashit( $domain . bp_get_members_invitations_slug() . '/list-invites' ); 3230 3231 /** 3232 * Filters the read notifications permalink. 3233 * 3234 * @since 7.0.0 3235 * 3236 * @param string $retval Permalink for the sent invitation list screen. 3237 * @param int $user_id The user ID. 3238 */ 3239 return apply_filters( 'bp_get_network_invitations_list_invites_permalink', $retval, $user_id ); 3240 } 3241 3242 /** 3243 * Output the read notifications permalink for a user. 3244 * 3245 * @since 7.0.0 3246 * 3247 * @param int $user_id The user ID. 3248 */ 3249 function bp_network_invitations_send_invites_permalink( $user_id = 0 ) { 3250 echo bp_get_network_invitations_send_invites_permalink( $user_id ); 3251 } 3252 /** 3253 * Return the read notifications permalink. 3254 * 3255 * @since 7.0.0 3256 * 3257 * @return string Read notifications permalink. 3258 */ 3259 function bp_get_network_invitations_send_invites_permalink( $user_id = 0 ) { 3260 if ( 0 === $user_id ) { 3261 $user_id = bp_loggedin_user_id(); 3262 $domain = bp_loggedin_user_domain(); 3263 } else { 3264 $domain = bp_core_get_user_domain( (int) $user_id ); 3265 } 3266 3267 $retval = trailingslashit( $domain . bp_get_members_invitations_slug() . '/send-invites' ); 3268 3269 /** 3270 * Filters the read notifications permalink. 3271 * 3272 * @since 7.0.0 3273 * 3274 * @param string $retval Permalink for the sent invitation list screen. 3275 * @param int $user_id The user ID. 3276 */ 3277 return apply_filters( 'bp_get_network_invitations_send_invites_permalink', $retval, $user_id ); 3278 } 3279 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..f31cb05d2 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->network_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_network_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_network_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['network_invitations'] = $this->network_invites_page = add_users_page( 498 __( 'Manage Invitations', 'buddypress' ), 499 __( 'Manage Invitations', 'buddypress' ), 500 $this->capability, 501 'bp-network-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->network_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 network_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..1d4fde57a 100644
class BP_Members_Component extends BP_Component { 64 64 'blocks', 65 65 'widgets', 66 66 'cache', 67 'notifications', 68 'invitations', 67 69 ); 68 70 69 71 if ( bp_is_active( 'activity' ) ) { … … class BP_Members_Component extends BP_Component { 137 139 // Theme compatibility. 138 140 new BP_Registration_Theme_Compat(); 139 141 } 142 143 // Invitations. 144 if ( is_user_logged_in() && bp_is_user_network_invitations() ) { 145 if ( bp_is_user_network_invitations_send_screen() ) { 146 require $this->path . 'bp-members/screens/send-invites.php'; 147 } else { 148 require $this->path . 'bp-members/screens/list-invites.php'; 149 } 150 } 140 151 } 141 152 142 153 /** … … class BP_Members_Component extends BP_Component { 231 242 $bp->profile->slug = 'profile'; 232 243 $bp->profile->id = 'profile'; 233 244 } 245 246 /** Network Invitations ************************************************** 247 */ 248 249 $bp->network_invitations = new stdClass; 234 250 } 235 251 236 252 /** … … class BP_Members_Component extends BP_Component { 466 482 } 467 483 } 468 484 469 470 485 parent::setup_nav( $main_nav, $sub_nav ); 471 486 } 472 487 -
new file src/bp-members/classes/class-bp-network-invitation-manager.php
diff --git src/bp-members/classes/class-bp-network-invitation-manager.php src/bp-members/classes/class-bp-network-invitation-manager.php new file mode 100644 index 000000000..154d21264
- + 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_Network_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-network-invitation', 55 ); 56 $invite_url = esc_url( add_query_arg( array( 57 'inv' => $invitation->id, 58 'ih' => bp_network_invitation_get_hash( $invitation ), 59 ), bp_get_signup_page() ) ); 60 61 $args = array( 62 'tokens' => array( 63 'displayname' => $invitation->invitee_email, 64 'network.url' => get_site_url( bp_get_root_blog_id() ), 65 'network.name' => get_bloginfo( 'name' ), 66 'network.description' => get_bloginfo( 'description' ), 67 'inviter.name' => bp_core_get_userlink( $invitation->inviter_id, true, false, true ), 68 'inviter.url' => bp_core_get_user_domain( $invitation->inviter_id ), 69 'inviter.id' => $invitation->inviter_id, 70 'invites.url' => $invite_url, 71 'invite.message' => $invitation->content, 72 // @TODO: add unsubscribe method that isn't reliant on user being a member of the site. 73 // 'unsubscribe' => esc_url( bp_email_get_unsubscribe_link( $unsubscribe_args ) ), 74 ), 75 ); 76 77 return bp_send_email( 'bp-network-invitation', $invitation->invitee_email, $args ); 78 } 79 } 80 81 /** 82 * This is where custom actions are added to run when an invitation 83 * or request is accepted. 84 * 85 * @since 7.0.0 86 * 87 * @param string $type Are we accepting an invitation or request? 88 * @param array $r Parameters that describe the invitation being accepted. 89 * @return bool True on success, false on failure. 90 */ 91 public function run_acceptance_action( $type = 'invite', $r ) { 92 // If the user is already a member (because BP at one point allowed two invitations to 93 // slip through), return early. 94 95 if ( 'request' === $type ) { 96 /** 97 * Fires after a network membership request has been accepted. 98 * 99 * @since 1.0.0 100 * 101 * @param int $user_id ID of the user who accepted membership. 102 * @param int $group_id ID of the group that was accepted membership to. 103 */ 104 do_action( 'network_membership_request_accepted', $r['user_id'], $r['item_id'] ); 105 } else { 106 /** 107 * Fires after a user has accepted a group invite. 108 * 109 * @since 1.0.0 110 * @since 2.8.0 The $inviter_id arg was added. 111 * 112 * @param int $user_id ID of the user who accepted the membership invite. 113 * @param int $inviter_id ID of the user who invited this user to the group. 114 */ 115 do_action( 'network_membership_invite_accepted', $r['user_id'], $inviter_id ); 116 } 117 118 119 return true; 120 } 121 122 /** 123 * Should this invitation be created? 124 * 125 * @since 7.0.0 126 * 127 * @param array $args. 128 * @return bool 129 */ 130 public function allow_invitation( $args ) { 131 // Does the inviter have this capability? 132 if ( ! bp_user_can( $args['inviter_id'], 'bp_network_send_invitation' ) ) { 133 return false; 134 } 135 136 // Is the invited user eligible to receive an invitation? Hasn't opted out? 137 if ( ! bp_user_can( 0, 'bp_network_receive_invitation', $args ) ) { 138 return false; 139 } 140 141 return true; 142 } 143 144 /** 145 * Should this request be created? 146 * 147 * @since 7.0.0 148 * 149 * @param array $args. 150 * @return bool. 151 */ 152 public function allow_request( $args ) { 153 // Does the requester have this capability? 154 if ( ! bp_user_can( 0, 'bp_network_request_membership', $args ) ) { 155 return false; 156 } 157 158 return true; 159 } 160 } -
new file src/bp-members/classes/class-bp-network-invitations-list-table.php
diff --git src/bp-members/classes/class-bp-network-invitations-list-table.php src/bp-members/classes/class-bp-network-invitations-list-table.php new file mode 100644 index 000000000..01867e8e4
- + 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_Network_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_Network_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-network-invitations-template.php
diff --git src/bp-members/classes/class-bp-network-invitations-template.php src/bp-members/classes/class-bp-network-invitations-template.php new file mode 100644 index 000000000..4c6ba5322
- + 1 <?php 2 /** 3 * BuddyPress Network_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_Network_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_network_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_network_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_Network_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_network_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..99f6e8c51
- + 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_network_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_network_invitation_cancel_' . $id ) && bp_network_invitation_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 ) && $scs = bp_network_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_network_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..2ff8860ae 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_network_invitations_allowed() ) { 48 // Check to see if there's a valid invitation. 49 $maybe_invite = bp_get_network_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..60f28f9e9
- + 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_network_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_network_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_network_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/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..1589b4c0d 100644
89 89 elseif ( bp_is_user_notifications() ) : 90 90 bp_get_template_part( 'members/single/notifications' ); 91 91 92 elseif ( bp_is_user_network_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..e52d39ff8
- + 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_network_invitations() ) : bp_the_network_invitation(); ?> 32 33 <tr> 34 <td></td> 35 <td class="bulk-select-check"><label for="<?php bp_the_network_invitation_property( 'id' ); ?>"><input id="<?php bp_the_network_invitation_property( 'id' ); ?>" type="checkbox" name="network_invitations[]" value="<?php bp_the_network_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_network_invitation_property( 'invitee_email' ); ?></td> 40 <td class="invitation-content"><?php wptexturize( bp_the_network_invitation_property( 'content' ) ); ?></td> 41 <td class="invitation-sent"><?php bp_the_network_invitation_property( 'invite_sent' ); ?></td> 42 <td class="invitation-accepted"><?php bp_the_network_invitation_property( 'accepted' ); ?></td> 43 <td class="invitation-date-modified"><?php bp_the_network_invitation_property( 'date_modified' ); ?></td> 44 <td class="invitation-actions"><?php bp_the_network_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..57b79bad9
- + 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_network_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_network_invitations_pagination_count(); ?> 21 </div> 22 23 <div class="pagination-links" id="invitations-pag-top"> 24 <?php bp_network_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_network_invitations_pagination_count(); ?> 33 </div> 34 35 <div class="pagination-links" id="invitations-pag-bottom"> 36 <?php bp_network_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> -
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 d4610aad4..a64935ed1 100644
class BuddyPress { 614 614 'BP_REST_Attachments_Member_Avatar_Endpoint' => 'members', 615 615 'BP_REST_Attachments_Member_Cover_Endpoint' => 'members', 616 616 'BP_REST_Signup_Endpoint' => 'members', 617 'BP_Network_Invitation_Manager' => 'members', 618 'BP_Network_Invitations_Template' => 'members', 617 619 618 620 'BP_REST_Messages_Endpoint' => 'messages', 619 621