Skip to:
Content

BuddyPress.org

Ticket #8582: 8582.1.diff

File 8582.1.diff, 47.9 KB (added by dcavins, 2 years ago)

Add request membership capability. First draft.

  • 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 b37b914ff..29d7ce4f5 100644
    function bp_admin_setting_callback_members_invitations() { 
    203203        do_action( 'bp_admin_settings_after_members_invitations' );
    204204}
    205205
     206/**
     207 * Allow new users to request membership to the network.
     208 *
     209 * @since 10.0.0
     210 */
     211function bp_admin_setting_callback_membership_requests() {
     212?>
     213        <input id="bp-enable-membership-requests" name="bp-enable-membership-requests" type="checkbox" value="1" <?php checked( bp_get_membership_requests_required( 'raw' ) ); ?> />
     214        <label for="bp-enable-membership-requests"><?php _e( 'Enable network membership requests. If enabled, an administrator must approve each new network membership.', 'buddypress' ); ?></label>
     215        <?php if ( bp_get_signup_allowed() ) : ?>
     216                <p class="description"><?php _e( 'Public registration is currently enabled. If you wish to require approval for new memberships, disable public registration and enable the membership requests feature.', 'buddypress' ); ?></p>
     217        <?php endif; ?>
     218        <?php
     219        /**
     220         * Fires after the output of the membership requests settings section.
     221         *
     222         * @since 10.0.0
     223         */
     224        do_action( 'bp_admin_settings_after_membership_requests' );
     225}
     226
    206227/** XProfile ******************************************************************/
    207228
    208229/**
  • src/bp-core/bp-core-functions.php

    diff --git src/bp-core/bp-core-functions.php src/bp-core/bp-core-functions.php
    index 3dbc32f11..ba99e6e57 100644
    function bp_core_replace_tokens_in_text( $text, $tokens ) { 
    38003800 * Get a list of emails for populating the email post type.
    38013801 *
    38023802 * @since 2.5.1
     3803 * @since 10.0.0 Added members-membership-request email type.
    38033804 *
    38043805 * @return array
    38053806 */
    function bp_email_get_schema() { 
    39603961                        /* translators: do not remove {} brackets or translate its contents. */
    39613962                        'post_excerpt' => __( "{{inviter.name}} has invited you to join the site \"{{site.name}}\".\n\n{{usermessage}}\n\nTo accept your invitation, visit: {{{invite.accept_url}}}\n\nTo learn more about the site, visit: {{{site.url}}}.\nTo view {{inviter.name}}'s profile, visit: {{{inviter.url}}}", 'buddypress' ),
    39623963                ),
     3964                'members-membership-request' => array(
     3965                        /* translators: do not remove {} brackets or translate its contents. */
     3966                        'post_title'   => __( '{{requesting-user.name}} would like to join {{site.name}}', 'buddypress' ),
     3967                        /* translators: do not remove {} brackets or translate its contents. */
     3968                        'post_content' => __( "<a href=\"{{{profile.url}}}\">{{requesting-user.name}}</a> would like to join the site: &quot;{{site.name}}&quot;.\n\n<a href=\"{{{manage.url}}}\">Manage the request</a> or <a href=\"{{{site.url}}}\">visit the site</a> to learn more.", 'buddypress' ),
     3969                        /* translators: do not remove {} brackets or translate its contents. */
     3970                        'post_excerpt' => __( "{{requesting-user.name}} would like to join the site \"{{site.name}}\".\n\nTo manage the request, visit: {{{manage.url}}}\n\nTo learn more about the site, visit: {{{site.url}}}.\nTo view {{requesting-user.name}}'s profile, visit: {{{profile.url}}}", 'buddypress' ),
     3971                ),
    39633972        ) );
    39643973}
    39653974
    function bp_email_get_type_schema( $field = 'description' ) { 
    41324141                ),
    41334142        );
    41344143
     4144        $members_membership_request= array(
     4145                'description'      => __( 'Someone has requested membership on this site.', 'buddypress' ),
     4146                'named_salutation' => true,
     4147                'unsubscribe'      => array(
     4148                        'meta_key' => 'notification_members_membership_request',
     4149                        'message'  => __( 'You will no longer receive emails when people submit requests to join this site.', 'buddypress' ),
     4150                ),
     4151        );
     4152
    41354153        $types = array(
    41364154                'activity-comment'                   => $activity_comment,
    41374155                'activity-comment-author'            => $activity_comment_author,
    function bp_email_get_type_schema( $field = 'description' ) { 
    41514169                'groups-membership-request-rejected' => $groups_membership_request_rejected,
    41524170                'core-user-activation'               => $core_user_activation,
    41534171                'bp-members-invitation'              => $members_invitation,
     4172                'members-membership-request'         => $members_membership_request,
     4173
    41544174        );
    41554175
    41564176        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 efb251957..87a16b7a6 100644
    function bp_get_title_parts( $seplocation = 'right' ) { 
    31923192
    31933193        // Sign up page.
    31943194        } elseif ( bp_is_register_page() ) {
    3195                 $bp_title_parts = array( __( 'Create an Account', 'buddypress' ) );
     3195                if ( bp_get_membership_requests_required() ) {
     3196                        $bp_title_parts = array( __( 'Request Membership', 'buddypress' ) );
     3197                } else {
     3198                        $bp_title_parts = array( __( 'Create an Account', 'buddypress' ) );
     3199                }
    31963200
    31973201        // Activation page.
    31983202        } elseif ( bp_is_activation_page() ) {
  • src/bp-core/bp-core-update.php

    diff --git src/bp-core/bp-core-update.php src/bp-core/bp-core-update.php
    index 03710213c..533efdb86 100644
    function bp_core_get_8_0_upgrade_email_schema( $emails ) { 
    704704        return $new_emails;
    705705}
    706706
     707/**
     708 * 10.0.0 update routine.
     709 *
     710 * - Explicitly set all signups to count_sent = 1 & sent_date to registered_date
     711 *
     712 * @since 10.0.0
     713 */
     714function bp_update_to_10_0() {
     715
     716        // @TODO: Explicitly set all signups to count_sent = 1 & sent_date to registered_date
     717        // Is there any way to update that meta in bulk? I think it will have to be one at a time.
     718
     719}
     720
    707721/**
    708722 * Updates the component field for new_members type.
    709723 *
  • 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 ee80328cc..191a8dfb8 100644
    class BP_Admin { 
    415415                if ( bp_is_active( 'members', 'invitations' ) ) {
    416416                        add_settings_field( 'bp-enable-members-invitations', __( 'Invitations', 'buddypress' ), 'bp_admin_setting_callback_members_invitations', 'buddypress', 'bp_members' );
    417417                        register_setting( 'buddypress', 'bp-enable-members-invitations', 'intval' );
     418
     419                        add_settings_field( 'bp-enable-membership-requests', __( 'Membership Requests', 'buddypress' ), 'bp_admin_setting_callback_membership_requests', 'buddypress', 'bp_members' );
     420                        register_setting( 'buddypress', 'bp-enable-membership-requests', 'intval' );
    418421                }
    419422
    420423                /* XProfile Section **************************************************/
  • src/bp-members/bp-members-filters.php

    diff --git src/bp-members/bp-members-filters.php src/bp-members/bp-members-filters.php
    index e1a0c69fd..c536e639d 100644
    function bp_members_sanitize_invitation_property( $value = '', $property = '', $ 
    366366        return $value;
    367367}
    368368add_filter( 'bp_the_members_invitation_property', 'bp_members_sanitize_invitation_property', 10, 3 );
     369
     370/**
     371 * Filter the actions available on the signups list table.
     372 *
     373 * @since 10.0.0
     374 *
     375 * @param array  $actions       Array of actions and corresponding links.
     376 * @param object $signup_object The signup data object.
     377 */
     378function bp_members_membership_requests_filter_signup_row_actions( $actions, $signup_object ) {
     379        if ( bp_get_membership_requests_required() ) {
     380                // Rename the "email" resend option when membership requests are active.
     381                $email_link = add_query_arg(
     382                        array(
     383                                'page'      => 'bp-signups',
     384                                'signup_id' => $signup_object->id,
     385                                'action'    => 'resend',
     386                        ),
     387                        bp_get_admin_url( 'users.php' )
     388                );
     389
     390                $resend_label = ( 0 === $signup_object->count_sent ) ? __( 'Approve Request', 'buddypress' ) : __( 'Resend Approval', 'buddypress' );
     391
     392                $actions['resend']   = sprintf( '<a href="%1$s">%2$s</a>', esc_url( $email_link ), $resend_label );
     393
     394                /*
     395                 * Add an "extended" link to the row action on the pending users table
     396                 * so admins can see what registration info the user supplied on the
     397                 * request membership form.
     398                 * http://bpdev.local/wp-admin/users.php?page=bp-profile-edit&user_id=40
     399                 http://bpdev.local/wp-admin/users.php?page=bp-signups&=http://bpdev.local/wp-admin/users.php?page=bp-profile-edit&user_id=38
     400                 *
     401                 */
     402                $user = get_user_by( 'email', $signup_object->user_email );
     403                if ( $user ) {
     404                        $edit_profile_args = array(
     405                                'page'    => 'bp-profile-edit',
     406                                'user_id' => $user->ID,
     407                        );
     408                        if ( is_network_admin() ) {
     409                                $base_edit_url = network_admin_url( 'users.php' );
     410                        } else {
     411                                $base_edit_url = admin_url( 'users.php' );
     412                        }
     413                        $edit_profile      = add_query_arg( $edit_profile_args, $base_edit_url );
     414                        $edit_profile_link = sprintf( '<a href="%1$s">%2$s</a>',  esc_url( $edit_profile ), esc_html__( 'Extended', 'buddypress' ) );
     415
     416                        $new_edit_actions = array( 'edit-profile' => $edit_profile_link );
     417
     418                        $actions = array_merge( $new_edit_actions, $actions );
     419                }
     420        }
     421        return $actions;
     422        //@TODO add help to manage signups screen:
     423        // Activate will activate the user immediately without requiring that they validate their email.
     424        // Approve Request will send the user an activation email, so they will still need to take action. This also will check that the user's email address is valid.
     425}
     426add_filter( 'bp_members_ms_signup_row_actions', 'bp_members_membership_requests_filter_signup_row_actions', 10, 2 );
     427
     428/**
     429 * Filter the bulk actions available on the signups list table.
     430 *
     431 * @since 10.0.0
     432 *
     433 * @param array  $actions       Array of actions and corresponding links.
     434 */
     435function bp_members_membership_requests_filter_signup_bulk_actions( $actions ) {
     436        if ( bp_get_membership_requests_required() ) {
     437                // Rename the "email" resend option when membership requests are active.
     438                $actions['resend'] = _x( 'Approve', 'Pending signup action', 'buddypress' );
     439        }
     440        return $actions;
     441}
     442add_filter( 'bp_members_ms_signup_bulk_actions', 'bp_members_membership_requests_filter_signup_bulk_actions' );
     443
     444/**
     445 * Filter the "Last Sent" column header on the pending users table.
     446 *
     447 * @since 10.0.0
     448 *
     449* @param array $value Array of columns to display.
     450 */
     451function bp_members_membership_requests_filter_signup_table_date_sent_header( $columns ) {
     452        if ( bp_get_membership_requests_required() ) {
     453                $columns['date_sent'] = __( 'Approved', 'buddypress' );
     454        }
     455        return $columns;
     456}
     457add_filter( 'bp_members_signup_columns', 'bp_members_membership_requests_filter_signup_table_date_sent_header' );
     458add_filter( 'bp_members_ms_signup_columns', 'bp_members_membership_requests_filter_signup_table_date_sent_header' );
     459
     460/**
     461 * Filter the "Last Sent" column message on the pending users table.
     462 *
     463 * @since 10.0.0
     464 *
     465 * @param string      $message "Not yet sent" message.
     466 * @param object|null $signup  Signup object instance.
     467 */
     468function bp_members_membership_requests_filter_signup_table_unsent_message( $message, $signup ) {
     469        if ( bp_get_membership_requests_required() && 0 === $signup->count_sent ) {
     470                $message = __( 'Not yet approved', 'buddypress' );
     471        }
     472        return $message;
     473}
     474add_filter( 'bp_members_signup_date_sent_unsent_message', 'bp_members_membership_requests_filter_signup_table_unsent_message', 10, 2 );
     475add_filter( 'bp_members_ms_signup_date_sent_unsent_message', 'bp_members_membership_requests_filter_signup_table_unsent_message', 10, 2 );
     476
  • src/bp-members/bp-members-functions.php

    diff --git src/bp-members/bp-members-functions.php src/bp-members/bp-members-functions.php
    index 93fd7cafd..2099c7d90 100644
    function bp_core_signup_send_validation_email( $user_id, $user_email, $key, $sal 
    23882388        bp_send_email( 'core-user-registration', $to, $args );
    23892389
    23902390        // Record that the activation email has been sent.
    2391         $signups = BP_Signup::get(
    2392                 array(
    2393                         'activation_key' => $key,
    2394                 )
    2395         );
     2391        $signup = bp_members_get_signup_by( 'activation_key', $key );
    23962392
    2397         if ( ! empty( $signups['signups'] ) ) {
    2398                 foreach ( $signups['signups'] as $signup ) {
    2399                         $meta = array(
    2400                                 'sent_date'  => current_time( 'mysql', true ),
    2401                                 'count_sent' => $signup->count_sent + 1
    2402                         );
     2393        if ( $signup ) {
     2394                $meta = array(
     2395                        'sent_date'  => current_time( 'mysql', true ),
     2396                        'count_sent' => $signup->count_sent + 1
     2397                );
    24032398
    2404                         BP_Signup::update( array(
    2405                                 'signup_id' => $signup->id,
    2406                                 'meta'      => $meta,
    2407                         ) );
    2408                 }
     2399                BP_Signup::update( array(
     2400                        'signup_id' => $signup->id,
     2401                        'meta'      => $meta,
     2402                ) );
    24092403        }
    24102404}
    24112405
    function bp_core_signup_disable_inactive( $user = null, $username = '', $passwor 
    24502444        }
    24512445
    24522446        // Unactivated user account found!
    2453         // Set up the feedback message.
    2454         $signup_id = $signup['signups'][0]->signup_id;
     2447        /*
     2448         * Don't allow users to resend their own activation email
     2449         * when membership requests are enabled.
     2450         */
     2451        if ( bp_get_membership_requests_required() ) {
     2452                return new WP_Error( 'bp_account_not_activated', __( '<strong>Error</strong>: Your membership request has not yet been approved.', 'buddypress' ) );
     2453        } else {
     2454                // Set up the feedback message.
     2455                $signup_id = $signup['signups'][0]->signup_id;
    24552456
    2456         $resend_url_params = array(
    2457                 'action' => 'bp-resend-activation',
    2458                 'id'     => $signup_id,
    2459         );
     2457                $resend_url_params = array(
     2458                        'action' => 'bp-resend-activation',
     2459                        'id'     => $signup_id,
     2460                );
    24602461
    2461         $resend_url = wp_nonce_url(
    2462                 add_query_arg( $resend_url_params, wp_login_url() ),
    2463                 'bp-resend-activation'
    2464         );
     2462                $resend_url = wp_nonce_url(
     2463                        add_query_arg( $resend_url_params, wp_login_url() ),
     2464                        'bp-resend-activation'
     2465                );
    24652466
    2466         $resend_string = '<br /><br />';
     2467                $resend_string = '<br /><br />';
    24672468
    2468         /* translators: %s: the activation url */
    2469         $resend_string .= sprintf( __( 'If you have not received an email yet, <a href="%s">click here to resend it</a>.', 'buddypress' ), esc_url( $resend_url ) );
     2469                /* translators: %s: the activation url */
     2470                $resend_string .= sprintf( __( 'If you have not received an email yet, <a href="%s">click here to resend it</a>.', 'buddypress' ), esc_url( $resend_url ) );
    24702471
    2471         return new WP_Error( 'bp_account_not_activated', __( '<strong>Error</strong>: Your account has not been activated. Check your email for the activation link.', 'buddypress' ) . $resend_string );
     2472                return new WP_Error( 'bp_account_not_activated', __( '<strong>Error</strong>: Your account has not been activated. Check your email for the activation link.', 'buddypress' ) . $resend_string );
     2473        }
    24722474}
    24732475add_filter( 'authenticate', 'bp_core_signup_disable_inactive', 30, 3 );
    24742476
    function bp_get_members_invitation_from_request() { 
    36943696         */
    36953697        return apply_filters( 'bp_get_members_invitation_from_request', $invite );
    36963698}
     3699
     3700/**
     3701 * Get WP_User object corresponding to a record in the signups table.
     3702 *
     3703 * @since 10.0.0
     3704 *
     3705 * @param string $field Which fields to search by. Possible values are
     3706 *                      activation_key, user_email, id.
     3707 * @param string $value Value to search by.
     3708 * @return bool|WP_User $user Found user, returns first found
     3709 *                            if more than one is found.
     3710 */
     3711function bp_members_get_user_from_signup_field( $field = 'activation_key', $value ) {
     3712        $signup = bp_members_get_signup_by( $field, $value );
     3713
     3714        if ( $signup ) {
     3715                $user = get_user_by( 'email', $signup->user_email );
     3716        } else {
     3717                $user = false;
     3718        }
     3719
     3720        return $user;
     3721}
     3722
     3723/**
     3724 * Get WP_User object corresponding to a record in the signups table.
     3725 *
     3726 * @since 10.0.0
     3727 *
     3728 * @param string $field Which fields to search by. Possible values are
     3729 *                      activation_key, user_email, id.
     3730 * @param string $value Value to search by.
     3731 * @return bool|BP_Signup $signup Found signup, returns first found
     3732 *                                if more than one is found.
     3733 */
     3734function bp_members_get_signup_by( $field = 'activation_key', $value ) {
     3735        switch ( $field ) {
     3736                case 'activation_key':
     3737                case 'user_email':
     3738                        $key = $field;
     3739                        break;
     3740
     3741                case 'id':
     3742                default:
     3743                        $key = 'include';
     3744                        break;
     3745        }
     3746
     3747        $signups = BP_Signup::get(
     3748                array(
     3749                        $key => $value,
     3750                )
     3751        );
     3752
     3753        if ( ! empty( $signups['signups'] ) ) {
     3754                $signup = current( $signups['signups'] );
     3755        } else {
     3756                $signup = false;
     3757        }
     3758
     3759        return $signup;
     3760}
  • src/bp-members/bp-members-invitations.php

    diff --git src/bp-members/bp-members-invitations.php src/bp-members/bp-members-invitations.php
    index 94e05e5bf..ebf20a74d 100644
    function bp_members_invitations_delete_optedout_invites( $optout ) { 
    162162        );
    163163}
    164164add_action( 'bp_optout_after_save', 'bp_members_invitations_delete_optedout_invites' );
     165
     166/**
     167 * If a user submits a site membership request, but there's a
     168 * sent invitation to her, bypass the manual approval of the request.
     169 *
     170 * @since 10.0.0
     171 *
     172 * @param bool  $send    Whether or not this membership request should be approved
     173 *                       immediately and the activation email sent.
     174 *                       Default is `false` meaning that the request should be
     175 *                       manually approved by a site admin.
     176 * @param array $details The details of the request.
     177 */
     178function bp_members_invitations_maybe_bypass_request_approval( $send, $details ) {
     179        if ( ! bp_get_members_invitations_allowed() ) {
     180                return $send;
     181        }
     182
     183        // We'll need the prospective user's email address.
     184        if ( empty( $details['user_email'] ) ) {
     185                return $send;
     186        }
     187
     188        $invites = bp_members_invitations_get_invites(
     189                array(
     190                        'invitee_email' => $details['user_email'],
     191                        'invite_sent'   => 'sent'
     192                )
     193        );
     194        // If pending invitations exist, send the verification mail.
     195        if ( $invites ) {
     196                $send = true;
     197        }
     198        return $send;
     199}
     200add_filter( 'bp_members_membership_requests_bypass_manual_approval', 'bp_members_invitations_maybe_bypass_request_approval', 10, 2 );
  • new file src/bp-members/bp-members-membership-requests.php

    diff --git src/bp-members/bp-members-membership-requests.php src/bp-members/bp-members-membership-requests.php
    new file mode 100644
    index 000000000..d040b2432
    - +  
     1<?php
     2/**
     3 * BuddyPress Membership Requests
     4 *
     5 * @package BuddyPress
     6 * @subpackage MembersMembershipRequest
     7 * @since 10.0.0
     8 */
     9
     10// Exit if accessed directly.
     11defined( 'ABSPATH' ) || exit;
     12
     13
     14/**
     15 * When a user creates a network membership request,
     16 * prevent the sending of the activation email so that
     17 * the site admins can send it later.
     18 *
     19 * @since 10.0.0
     20 *
     21 * @param bool   $send           Whether or not to send the activation key.
     22 * @param int    $user_id        User ID to send activation key to.
     23 * @param string $user_email     User email to send activation key to.
     24 * @param string $activation_key Activation key to be sent.
     25 * @param array  $usermeta       Miscellaneous metadata about the user (blog-specific
     26 *                               signup data, xprofile data, etc).
     27 * @return bool Whether or not to send the activation key.
     28 */
     29function bp_members_membership_requests_cancel_activation_email( $send, $user_id = 0, $user_email = '', $activation_key = '', $usermeta = array() ) {
     30
     31        if ( bp_get_membership_requests_required() ) {
     32                $details = array(
     33                        'user_id'        => $user_id,
     34                        'user_email'     => $user_email,
     35                        'activation_key' => $activation_key,
     36                        'usermeta'       => $usermeta,
     37                );
     38
     39                /**
     40                 * Allow some membership requests to be approved immediately.
     41                 * For example, you might want to approve all requests
     42                 * coming from users with certain email address domains.
     43                 * If `true` is returned the activation email will be sent to the user.
     44                 *
     45                 * @since 10.0.0
     46                 *
     47                 * @param bool  $send    Whether or not this membership request should be approved
     48                 *                       immediately and the activation email sent.
     49                 *                       Default is `false` meaning that the request should be
     50                 *                       manually approved by a site admin.
     51                 * @param array $details The details of the request.
     52                 */
     53                $send = apply_filters( 'bp_members_membership_requests_bypass_manual_approval', false, $details );
     54
     55                // If the registration process has been interrupted, this is a new membership request.
     56                if ( ! $send ) {
     57                        $signup = bp_members_get_signup_by( 'activation_key', $activation_key );
     58
     59                        /**
     60                         * Fires when a site membership request has been created and is pending.
     61                         *
     62                         * @since 10.0.0
     63                         *
     64                         * @param BP_Signup $signup  The signup object that has been created.
     65                         * @param array     $details The details of the request.
     66                         */
     67                        do_action( 'bp_members_membership_request_submitted', $signup, $details );
     68                }
     69        }
     70
     71        return $send;
     72}
     73add_filter( 'bp_core_signup_send_activation_key', 'bp_members_membership_requests_cancel_activation_email', 10, 5 );
     74
     75
     76/**
     77 * Notify site admins about a new membership request.
     78 *
     79 * @since 10.0.0
     80 *
     81 * @param BP_Signup $signup  The signup object that has been created.
     82 */
     83function bp_members_membership_requests_notify_site_admins( $signup ) {
     84        $requesting_user    = get_user_by( 'email', $signup->user_email );
     85        $requesting_user_id = isset( $requesting_user->ID ) ? $requesting_user->ID : 0;
     86
     87        $admins_query = new WP_User_Query( array(
     88                'role'   => 'administrator',
     89                'fields' => 'ids'
     90        ) );
     91        $admin_ids   = $admins_query->get_results();
     92
     93        foreach ( $admin_ids as $admin_id ) {
     94                // Trigger a BuddyPress Notification.
     95                if ( bp_is_active( 'notifications' ) ) {
     96                        bp_notifications_add_notification( array(
     97                                'user_id'           => $admin_id,
     98                                'item_id'           => $signup->signup_id,
     99                                'secondary_item_id' => $requesting_user_id,
     100                                'component_name'    => buddypress()->members->id,
     101                                'component_action'  => 'membership_request_submitted',
     102                                'date_notified'     => bp_core_current_time(),
     103                                'is_new'            => 1,
     104                        ) );
     105                }
     106
     107                // Bail if member opted out of receiving this email.
     108                if ( 'no' === bp_get_user_meta( $admin_id, 'notification_members_membership_request', true ) ) {
     109                        return;
     110                }
     111
     112                $unsubscribe_args = array(
     113                        'user_id'           => $admin_id,
     114                        'notification_type' => 'members-membership-request',
     115                );
     116                $manage_url = add_query_arg( array(
     117                        'mod_req'   => 1,
     118                        'page'      => 'bp-signups',
     119                        'signup_id' => $item_id,
     120                ), bp_get_admin_url( 'users.php' ) );
     121                $args  = array(
     122                        'tokens' => array(
     123                                'admin.id'             => $admin_id,
     124                                'manage.url'           => $manage_url,
     125                                'profile.url'          => esc_url( bp_core_get_user_domain( $requesting_user_id ) ),
     126                                'requesting-user.id'   => $requesting_user_id,
     127                                'requesting-user.name' => bp_core_get_user_displayname( $requesting_user_id ),
     128                                'unsubscribe'          => esc_url( bp_email_get_unsubscribe_link( $unsubscribe_args ) ),
     129                        ),
     130                );
     131                bp_send_email( 'members-membership-request', (int) $admin_id, $args );
     132        }
     133
     134}
     135add_action( 'bp_members_membership_request_submitted', 'bp_members_membership_requests_notify_site_admins' );
     136
     137/**
     138 * Add "Request Membership" link to Widget login form.
     139 *
     140 * @since 10.0.0
     141 *
     142 * @return string $retval the HTML for the request membership link.
     143 */
     144function bp_members_membership_requests_add_link_to_widget_login_form() {
     145        if ( ! bp_get_membership_requests_required() ) {
     146                return;
     147        }
     148        ?>
     149        <span class="bp-login-widget-request-membership-link"><a href="<?php echo esc_url( bp_get_signup_page() ); ?>"><?php _e( 'Request Membership', 'buddypress' ); ?></a></span>
     150        <?php
     151}
     152add_action( 'bp_login_widget_form', 'bp_members_membership_requests_add_link_to_widget_login_form' );
     153
     154/**
     155 * In the Nouveau template pack, when membership requests are required,
     156 * change registration form submit button label to "Submit Request".
     157 *
     158 * @since 10.0.0
     159 *
     160 * @return string $retval the HTML for the request membership link.
     161 */
     162function bp_members_membership_requests_filter_complete_signup_button( $buttons ) {
     163        if ( bp_get_membership_requests_required() ) {
     164                $buttons['register']['attributes']['value'] = __( 'Submit Request', 'buddypress' );
     165        }
     166        return $buttons;
     167}
     168add_filter( 'bp_nouveau_get_submit_button', 'bp_members_membership_requests_filter_complete_signup_button' );
  • src/bp-members/bp-members-notifications.php

    diff --git src/bp-members/bp-members-notifications.php src/bp-members/bp-members-notifications.php
    index 93cee7b89..0c9ff824a 100644
    function members_format_notifications( $action, $item_id, $secondary_item_id, $t 
    6161                                }
    6262                        }
    6363                        break;
     64
     65                case 'membership_request_submitted':
     66                        // $item_id is the id of the signup, not the user ID.
     67                        $user = bp_members_get_user_from_signup_field( 'id', $item_id );
     68
     69                        // Set up the string and the filter.
     70                        if ( (int) $total_items > 1 ) {
     71                                $link   = bp_get_notifications_permalink();
     72                                $amount = 'multiple';
     73
     74                                $text = sprintf( __( '%d people have requested site membership.', 'buddypress' ), (int) $total_items );
     75                        } else {
     76                                $link   = add_query_arg( array(
     77                                        'mod_req'   => 1,
     78                                        'page'      => 'bp-signups',
     79                                        'signup_id' => $item_id,
     80
     81                                ), bp_get_admin_url( 'users.php' ) );
     82                                $amount = 'single';
     83
     84                                /* translators: %s: new user name */
     85                                $text = sprintf( __( '%s has requested site membership.', 'buddypress' ),  bp_core_get_user_displayname( $user->ID ) );
     86                        }
     87                        break;
    6488        }
    6589
    6690        // Return either an HTML link or an array, depending on the requested format.
    function bp_members_mark_read_accepted_invitation_notification() { 
    167191                        'is_new' => false,
    168192                ),
    169193                array(
    170                         'user_id' => bp_loggedin_user_id(),
    171                         'item_id' => bp_displayed_user_id(),
     194                        'user_id'           => bp_loggedin_user_id(),
     195                        'item_id'           => bp_displayed_user_id(),
     196                        'component_action'  => 'accepted_invitation',
    172197                )
    173198        );
    174199}
    175200add_action( 'bp_screens', 'bp_members_mark_read_accepted_invitation_notification' );
    176201
     202/**
     203 * Mark new membership request notifications as read when user visits Manage BP Signups screen.
     204 *
     205 * @since 10.0.0
     206 */
     207function bp_members_mark_read_submitted_membership_request_notification() {
     208        if ( ! wp_doing_ajax() && 'users_page_bp-signups' === get_current_screen()->base && ! empty( $_GET['mod_req'] ) && ! empty( $_GET['signup_id'] ) ) {
     209                // Mark notification as read.
     210                BP_Notifications_Notification::update(
     211                        array(
     212                                'is_new' => false,
     213                        ),
     214                        array(
     215                                'user_id'           => bp_loggedin_user_id(),
     216                                'item_id'           => $_GET['signup_id'],
     217                                'component_action'  => 'membership_request_submitted',
     218                        )
     219                );
     220        }
     221}
     222add_action( 'admin_footer', 'bp_members_mark_read_submitted_membership_request_notification' );
     223
    177224/**
    178225 * Add Members-related settings to the Settings > Notifications page.
    179226 *
    add_action( 'bp_screens', 'bp_members_mark_read_accepted_invitation_notification 
    181228 */
    182229function members_screen_notification_settings() {
    183230
    184         // Bail early if invitations are not allowed--they are the only members notification so far.
    185         if ( ! bp_get_members_invitations_allowed () ) {
     231        // Bail early if invitations and requests are not allowed--they are the only members notification so far.
     232        if ( ! bp_get_members_invitations_allowed() && ( ! bp_get_membership_requests_required() || ! user_can( bp_displayed_user_id(), 'bp_moderate' ) ) ) {
    186233                return;
    187234        }
    188 
    189         if ( ! $allow_acceptance_emails = bp_get_user_meta( bp_displayed_user_id(), 'notification_members_invitation_accepted', true ) ) {
    190                 $allow_acceptance_emails = 'yes';
    191         }
    192235        ?>
    193236
    194237        <table class="notification-settings" id="members-notification-settings">
    function members_screen_notification_settings() { 
    202245                </thead>
    203246
    204247                <tbody>
    205                         <tr id="members-notification-settings-invitation_accepted">
    206                                 <td></td>
    207                                 <td><?php _ex( 'Someone accepts your membership invitation', 'Member settings on notification settings page', 'buddypress' ) ?></td>
    208                                 <td class="yes"><input type="radio" name="notifications[notification_members_invitation_accepted]" id="notification-members-invitation-accepted-yes" value="yes" <?php checked( $allow_acceptance_emails, 'yes', true ) ?>/><label for="notification-members-invitation-accepted-yes" class="bp-screen-reader-text"><?php
    209                                         /* translators: accessibility text */
    210                                         _e( 'Yes, send email', 'buddypress' );
    211                                 ?></label></td>
    212                                 <td class="no"><input type="radio" name="notifications[notification_members_invitation_accepted]" id="notification-members-invitation-accepted-no" value="no" <?php checked( $allow_acceptance_emails, 'no', true ) ?>/><label for="notification-members-invitation-accepted-no" class="bp-screen-reader-text"><?php
    213                                         /* translators: accessibility text */
    214                                         _e( 'No, do not send email', 'buddypress' );
    215                                 ?></label></td>
    216                         </tr>
    217248
    218249                        <?php
     250                        if ( bp_get_members_invitations_allowed() ) :
     251                                if ( ! $allow_acceptance_emails = bp_get_user_meta( bp_displayed_user_id(), 'notification_members_invitation_accepted', true ) ) {
     252                                        $allow_acceptance_emails = 'yes';
     253                                }
     254                                ?>
     255                                <tr id="members-notification-settings-invitation_accepted">
     256                                        <td></td>
     257                                        <td><?php _ex( 'Someone accepts your membership invitation', 'Member settings on notification settings page', 'buddypress' ) ?></td>
     258                                        <td class="yes"><input type="radio" name="notifications[notification_members_invitation_accepted]" id="notification-members-invitation-accepted-yes" value="yes" <?php checked( $allow_acceptance_emails, 'yes', true ) ?>/><label for="notification-members-invitation-accepted-yes" class="bp-screen-reader-text"><?php
     259                                                /* translators: accessibility text */
     260                                                _e( 'Yes, send email', 'buddypress' );
     261                                        ?></label></td>
     262                                        <td class="no"><input type="radio" name="notifications[notification_members_invitation_accepted]" id="notification-members-invitation-accepted-no" value="no" <?php checked( $allow_acceptance_emails, 'no', true ) ?>/><label for="notification-members-invitation-accepted-no" class="bp-screen-reader-text"><?php
     263                                                /* translators: accessibility text */
     264                                                _e( 'No, do not send email', 'buddypress' );
     265                                        ?></label></td>
     266                                </tr>
     267                                <?php
     268                        endif;
     269
     270                        if ( bp_get_membership_requests_required() && user_can( bp_displayed_user_id(), 'bp_moderate' ) ) :
     271                                if ( ! $allow_request_emails = bp_get_user_meta( bp_displayed_user_id(), 'notification_members_membership_request', true ) ) {
     272                                        $allow_request_emails = 'yes';
     273                                }
     274                                ?>
     275                                <tr id="members-notification-settings-submitted_membership_request">
     276                                        <td></td>
     277                                        <td><?php _ex( 'Someone has requested site membership', 'Member settings on notification settings page', 'buddypress' ) ?></td>
     278                                        <td class="yes"><input type="radio" name="notifications[notification_members_membership_request]" id="notification-members-submitted_membership_request-yes" value="yes" <?php checked( $allow_request_emails, 'yes', true ) ?>/><label for="notification-members-submitted_membership_request-yes" class="bp-screen-reader-text"><?php
     279                                                /* translators: accessibility text */
     280                                                _e( 'Yes, send email', 'buddypress' );
     281                                        ?></label></td>
     282                                        <td class="no"><input type="radio" name="notifications[notification_members_membership_request]" id="notification-members-submitted_membership_request-no" value="no" <?php checked( $allow_request_emails, 'no', true ) ?>/><label for="notification-members-submitted_membership_request-no" class="bp-screen-reader-text"><?php
     283                                                /* translators: accessibility text */
     284                                                _e( 'No, do not send email', 'buddypress' );
     285                                        ?></label></td>
     286                                </tr>
     287                                <?php
     288                        endif;
    219289
    220290                        /**
    221291                         * Fires after the last table row on the members notification screen.
  • src/bp-members/bp-members-template.php

    diff --git src/bp-members/bp-members-template.php src/bp-members/bp-members-template.php
    index 39cfd6e65..32864d043 100644
    function bp_get_members_invitations_allowed() { 
    29252925        return apply_filters( 'bp_get_members_invitations_allowed', bp_is_active( 'members', 'invitations' ) && (bool) bp_get_option( 'bp-enable-members-invitations' ) );
    29262926}
    29272927
     2928/**
     2929 * Are membership requests required for joining this site?
     2930 *
     2931 * @since 10.0.0
     2932 *
     2933 * @param bool $context "raw" to fetch value from database,
     2934 *                      "site" to take "anyone can register" setting into account.
     2935 * @return bool
     2936 */
     2937function bp_get_membership_requests_required( $context = 'site' ) {
     2938        if ( 'raw' === $context ) {
     2939                $retval = bp_is_active( 'members', 'invitations' ) && (bool) bp_get_option( 'bp-enable-membership-requests' );
     2940        } else {
     2941                $retval = bp_is_active( 'members', 'invitations' ) && ! bp_get_signup_allowed() && (bool) bp_get_option( 'bp-enable-membership-requests' );
     2942        }
     2943
     2944        /**
     2945         * Filters whether or not prospective members may submit network membership requests.
     2946         *
     2947         * @since 10.0.0
     2948         *
     2949         * @param bool $retval Whether or not membership requests are required.
     2950         * @param bool $retval Whether this is the value stored in the database ('raw')
     2951         *                     or whether the site's "anyone can register" setting is
     2952         *                     being considered ('site' or anything else).
     2953         */
     2954        return apply_filters( 'bp_get_membership_requests_required', $retval, $context );
     2955}
     2956
    29282957/**
    29292958 * Should the system create and allow access
    29302959 * to the Register and Activate pages?
    function bp_get_members_invitations_allowed() { 
    29342963 * @return bool
    29352964 */
    29362965function bp_allow_access_to_registration_pages() {
    2937         $retval = bp_get_signup_allowed() || bp_get_members_invitations_allowed();
     2966        $retval = bp_get_signup_allowed() || bp_get_members_invitations_allowed() || bp_get_membership_requests_required();
    29382967
    29392968        /**
    29402969         * Filters whether or not the system should create and allow access
  • 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 8027051b1..4dcad3d52 100644
    class BP_Members_Admin { 
    11201120
    11211121                // Bail if user has not been activated yet (how did you get here?).
    11221122                if ( isset( $user->user_status ) && ( 2 == $user->user_status ) ) : ?>
    1123 
    1124                         <p class="not-activated"><?php esc_html_e( 'User account has not yet been activated', 'buddypress' ); ?></p><br/>
    1125 
    1126                         <?php return;
    1127 
     1123                        <p class="not-activated"><?php esc_html_e( 'User account has not yet been activated', 'buddypress' ); ?></p>
     1124                        <?php
     1125                        if ( ! bp_get_membership_requests_required() ) {
     1126                                return;
     1127                        }
    11281128                endif; ?>
    11291129
    11301130                <div class="submitbox" id="submitcomment">
    class BP_Members_Admin { 
    11321132                                <div id="misc-publishing-actions">
    11331133                                        <?php
    11341134
    1135                                         // Get the spam status once here to compare against below.
    1136                                         $is_spammer = bp_is_user_spammer( $user->ID );
     1135                                        if ( ! bp_get_membership_requests_required() ) :
     1136
     1137                                                // Get the spam status once here to compare against below.
     1138                                                $is_spammer = bp_is_user_spammer( $user->ID );
     1139
     1140                                                /**
     1141                                                 * In configs where BuddyPress is not network activated,
     1142                                                 * regular admins cannot mark a user as a spammer on front
     1143                                                 * end. This prevent them to do it in the back end.
     1144                                                 *
     1145                                                 * Also prevent admins from marking themselves or other
     1146                                                 * admins as spammers.
     1147                                                 */
     1148                                                if ( ( empty( $this->is_self_profile ) && ( ! in_array( $user->user_login, get_super_admins() ) ) && empty( $this->subsite_activated ) ) || ( ! empty( $this->subsite_activated ) && current_user_can( 'manage_network_users' ) ) ) : ?>
     1149
     1150                                                        <div class="misc-pub-section" id="comment-status-radio">
     1151                                                                <label class="approved"><input type="radio" name="user_status" value="ham" <?php checked( $is_spammer, false ); ?>><?php esc_html_e( 'Active', 'buddypress' ); ?></label><br />
     1152                                                                <label class="spam"><input type="radio" name="user_status" value="spam" <?php checked( $is_spammer, true ); ?>><?php esc_html_e( 'Spammer', 'buddypress' ); ?></label>
     1153                                                        </div>
     1154
     1155                                                <?php endif; ?>
     1156                                        <?php elseif ( ! empty( $user->user_email ) ) :
     1157                                                // Provide details on the pending signup.
     1158                                                $signup   = bp_members_get_signup_by( 'user_email', $user->user_email );
     1159                                                $approved = ( $signup->count_sent > 0 );
     1160                                                $label    = $approved ? __( 'Approve request', 'buddypress' ) : __( 'Resend approval email', 'buddypress' );
     1161
     1162                                                $email_link = add_query_arg(
     1163                                                        array(
     1164                                                                'page'      => 'bp-signups',
     1165                                                                'signup_id' => $signup->id,
     1166                                                                'action'    => 'resend',
     1167                                                        ),
     1168                                                        bp_get_admin_url( 'users.php' )
     1169                                                );
     1170
     1171                                                $resend_label = $approved ? __( 'Resend Approval', 'buddypress' ) : __( 'Approve Request', 'buddypress' );
     1172
     1173                                                $approved_message = $approved ? mysql2date( 'Y/m/d g:i:s a', $signup->date_sent ) : __( 'Not yet approved', 'buddypress' );
     1174                                                ?>
     1175                                                        <div class="misc-pub-section" id="comment-status-radio">
     1176                                                                <p><?php printf( '<a href="%1$s" class="button">%2$s</a>', esc_url( $email_link ), $resend_label ); ?></p>
     1177
     1178                                                                <p><strong><?php _e( 'Approved', 'buddypress' ) ?></strong> <?php echo $approved_message; ?></p>
    11371179
    1138                                         /**
    1139                                          * In configs where BuddyPress is not network activated,
    1140                                          * regular admins cannot mark a user as a spammer on front
    1141                                          * end. This prevent them to do it in the back end.
    1142                                          *
    1143                                          * Also prevent admins from marking themselves or other
    1144                                          * admins as spammers.
    1145                                          */
    1146                                         if ( ( empty( $this->is_self_profile ) && ( ! in_array( $user->user_login, get_super_admins() ) ) && empty( $this->subsite_activated ) ) || ( ! empty( $this->subsite_activated ) && current_user_can( 'manage_network_users' ) ) ) : ?>
     1180                                                                <p><strong><?php _e( 'Emails Sent', 'buddypress' ) ?></strong> <?php echo $signup->count_sent; ?></p>
    11471181
    1148                                                 <div class="misc-pub-section" id="comment-status-radio">
    1149                                                         <label class="approved"><input type="radio" name="user_status" value="ham" <?php checked( $is_spammer, false ); ?>><?php esc_html_e( 'Active', 'buddypress' ); ?></label><br />
    1150                                                         <label class="spam"><input type="radio" name="user_status" value="spam" <?php checked( $is_spammer, true ); ?>><?php esc_html_e( 'Spammer', 'buddypress' ); ?></label>
    1151                                                 </div>
     1182                                                        </div>
    11521183
    1153                                         <?php endif ;?>
     1184                                        <?php endif; ?>
    11541185
    11551186                                        <div class="misc-pub-section curtime misc-pub-section-last">
    11561187                                                <?php
    class BP_Members_Admin { 
    11611192                                                ?>
    11621193                                                <span id="timestamp">
    11631194                                                        <?php
    1164                                                         /* translators: %s: registration date */
    1165                                                         printf( __( 'Registered on: %s', 'buddypress' ), '<strong>' . $date . '</strong>' );
     1195                                                        if ( ! bp_get_membership_requests_required() ) {
     1196                                                                /* translators: %s: registration date */
     1197                                                                $reg_message = __( 'Registered on: %s', 'buddypress' );
     1198                                                        } else {
     1199                                                                /* translators: %s: registration date */
     1200                                                                $reg_message = __( 'Requested membership on: %s', 'buddypress' );
     1201                                                        }
     1202                                                        printf( $reg_message, '<strong>' . $date . '</strong>' );
    11661203                                                        ?>
    11671204                                                </span>
    11681205                                        </div>
    class BP_Members_Admin { 
    21732210                ) );
    21742211
    21752212                $signups    = $signups_query['signups'];
    2176                 $signup_ids = wp_list_pluck( $signups, 'signup_id' );
     2213                $signup_ids = wp_list_pluck( $signups, 'id' );
    21772214
    21782215                // Set up strings.
    21792216                switch ( $action ) {
    class BP_Members_Admin { 
    22552292
    22562293                        <ol class="bp-signups-list">
    22572294                        <?php foreach ( $signups as $signup ) :
    2258                                 $last_notified = mysql2date( 'Y/m/d g:i:s a', $signup->date_sent );
     2295                                if ( $signup->count_sent > 0 ) {
     2296                                        $last_notified = mysql2date( 'Y/m/d g:i:s a', $signup->date_sent );
     2297                                } else {
     2298                                        $last_notified = __( 'Not yet notified', 'buddypress' );
     2299                                }
    22592300                                $profile_field_ids = array();
    22602301
    22612302                                // Get all xprofile field IDs except field 1.
  • 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 a7deff76d..a479619d4 100644
    class BP_Members_Component extends BP_Component { 
    6767                        'widgets',
    6868                        'cache',
    6969                        'invitations',
     70                        'membership-requests',
    7071                        'notifications',
    7172                );
    7273
  • src/bp-members/classes/class-bp-members-list-table.php

    diff --git src/bp-members/classes/class-bp-members-list-table.php src/bp-members/classes/class-bp-members-list-table.php
    index 8e7733b47..f659c3bea 100644
    class BP_Members_List_Table extends WP_Users_List_Table { 
    171171                        $actions['delete'] = __( 'Delete', 'buddypress' );
    172172                }
    173173
    174                 return $actions;
     174                /**
     175                 * Filters the bulk actions for signups.
     176                 *
     177                 * @since 10.0.0
     178                 *
     179                 * @param array $actions Array of actions and corresponding labels.
     180                 */
     181                return apply_filters( 'bp_members_ms_signup_bulk_actions', $actions );
    175182        }
    176183
    177184        /**
    class BP_Members_List_Table extends WP_Users_List_Table { 
    183190         */
    184191        public function no_items() {
    185192
    186                 if ( bp_get_signup_allowed() ) {
     193                if ( bp_get_signup_allowed() || bp_get_membership_requests_required() ) {
    187194                        esc_html_e( 'No pending accounts found.', 'buddypress' );
    188195                } else {
    189196                        $link = false;
    class BP_Members_List_Table extends WP_Users_List_Table { 
    374381         * @param object|null $signup_object The signup data object.
    375382         */
    376383        public function column_date_sent( $signup_object = null ) {
    377                 echo mysql2date( 'Y/m/d', $signup_object->date_sent );
     384                if ( $signup_object->count_sent > 0 ) {
     385                        echo mysql2date( 'Y/m/d', $signup_object->date_sent );
     386                } else {
     387                        $message = __( 'Not yet notified', 'buddypress' );
     388
     389                        /**
     390                         * Filters the "not yet sent" message for "Last Sent"
     391                         * column in Manage Signups list table.
     392                         *
     393                         * @since 10.0.0
     394                         *
     395                         * @param string      $message       "Not yet sent" message.
     396                         * @param object|null $signup_object Signup object instance.
     397                         */
     398                        $message = apply_filters( 'bp_members_signup_date_sent_unsent_message', $message, $signup_object );
     399
     400                        echo esc_html( $message );
     401                }
    378402        }
    379403
    380404        /**
  • src/bp-members/classes/class-bp-members-ms-list-table.php

    diff --git src/bp-members/classes/class-bp-members-ms-list-table.php src/bp-members/classes/class-bp-members-ms-list-table.php
    index b8e86f906..21f085b1d 100644
    class BP_Members_MS_List_Table extends WP_MS_Users_List_Table { 
    158158                        $actions['delete'] = __( 'Delete', 'buddypress' );
    159159                }
    160160
    161                 return $actions;
     161                /**
     162                 * Filters the bulk actions for signups.
     163                 *
     164                 * @since 10.0.0
     165                 *
     166                 * @param array $actions Array of actions and corresponding labels.
     167                 */
     168                return apply_filters( 'bp_members_ms_signup_bulk_actions', $actions );
    162169        }
    163170
    164171        /**
    class BP_Members_MS_List_Table extends WP_MS_Users_List_Table { 
    169176         * @since 2.0.0
    170177         */
    171178        public function no_items() {
    172                 if ( bp_get_signup_allowed() ) {
     179                if ( bp_get_signup_allowed() || bp_get_membership_requests_required() ) {
    173180                        esc_html_e( 'No pending accounts found.', 'buddypress' );
    174181                } else {
    175182                        $link = false;
    class BP_Members_MS_List_Table extends WP_MS_Users_List_Table { 
    376383                        $date = 'Y/m/d \<\b\r \/\> g:i:s a';
    377384                }
    378385
    379                 echo mysql2date( $date, $signup_object->date_sent );
     386                if ( $signup_object->count_sent > 0 ) {
     387                        echo mysql2date( $date, $signup_object->date_sent );
     388                } else {
     389                        $message = __( 'Not yet notified', 'buddypress' );
     390
     391                        /**
     392                         * Filters the "not yet sent" message for "Last Sent"
     393                         * column in Manage Signups list table.
     394                         *
     395                         * @since 10.0.0
     396                         *
     397                         * @param string      $message       "Not yet sent" message.
     398                         * @param object|null $signup_object Signup object instance.
     399                         */
     400                        $message = apply_filters( 'bp_members_ms_signup_date_sent_unsent_message', $message, $signup_object );
     401
     402                        echo esc_html( $message );
     403                }
    380404        }
    381405
    382406        /**
  • src/bp-members/classes/class-bp-registration-theme-compat.php

    diff --git src/bp-members/classes/class-bp-registration-theme-compat.php src/bp-members/classes/class-bp-registration-theme-compat.php
    index 6a942a58b..f4e3e6855 100644
    class BP_Registration_Theme_Compat { 
    9797        public function dummy_post() {
    9898                // Registration page.
    9999                if ( bp_is_register_page() ) {
    100                         $title = __( 'Create an Account', 'buddypress' );
     100                        if ( bp_get_membership_requests_required() ) {
     101                                $title = __( 'Request Membership', 'buddypress' );
     102                        } else {
     103                                $title = __( 'Create an Account', 'buddypress' );
     104                        }
    101105
    102106                        if ( 'completed-confirmation' == bp_get_current_signup_step() ) {
    103                                 $title = __( 'Check Your Email To Activate Your Account!', 'buddypress' );
     107                                if ( bp_get_membership_requests_required() ) {
     108                                        $title = __( 'Your Membership Request has been submitted.', 'buddypress' );
     109                                } else {
     110                                        $title = __( 'Check Your Email To Activate Your Account!', 'buddypress' );
     111                                }
    104112                        }
    105113
    106114                // Activation page.
  • src/bp-members/screens/register.php

    diff --git src/bp-members/screens/register.php src/bp-members/screens/register.php
    index 77929c442..40dd280dc 100644
    function bp_core_screen_signup() { 
    6161                }
    6262        }
    6363
    64         if ( ! bp_get_signup_allowed() && ! $active_invite ) {
     64        $requests_enabled = bp_get_membership_requests_required();
     65
     66        if ( ! bp_get_signup_allowed() && ! $active_invite && ! $requests_enabled ) {
    6567                $bp->signup->step = 'registration-disabled';
    6668                // If the signup page is submitted, validate and save.
    6769        } elseif ( isset( $_POST['signup_submit'] ) && bp_verify_nonce_request( 'bp_new_signup' ) ) {
  • src/bp-templates/bp-legacy/buddypress/members/register.php

    diff --git src/bp-templates/bp-legacy/buddypress/members/register.php src/bp-templates/bp-legacy/buddypress/members/register.php
    index d263470f2..dd6365b45 100644
     
    351351                         *
    352352                         * @since 1.1.0
    353353                         */
    354                         do_action( 'bp_before_registration_submit_buttons' ); ?>
     354                        do_action( 'bp_before_registration_submit_buttons' );
     355
     356                        if ( bp_get_membership_requests_required() ) {
     357                                $button_text = __( 'Submit Request', 'buddypress' );
     358                        } else {
     359                                $button_text = __( 'Complete Sign Up', 'buddypress' );
     360                        }
     361                        ?>
    355362
    356363                        <div class="submit">
    357                                 <input type="submit" name="signup_submit" id="signup_submit" value="<?php esc_attr_e( 'Complete Sign Up', 'buddypress' ); ?>" />
     364                                <input type="submit" name="signup_submit" id="signup_submit" value="<?php echo esc_attr( $button_text ); ?>" />
    358365                        </div>
    359366
    360367                        <?php
     
    390397                        do_action( 'bp_before_registration_confirmed' ); ?>
    391398
    392399                        <div id="template-notices" role="alert" aria-atomic="true">
    393                                 <?php if ( bp_registration_needs_activation() ) : ?>
     400                                <?php if ( bp_get_membership_requests_required() ) : ?>
     401                                        <p><?php _e( 'You have successfully submitted your membership request! Our site moderators will review your submission and send you an activation email if your request is approved.', 'buddypress' ); ?></p>
     402                                <?php elseif ( bp_registration_needs_activation() ) : ?>
    394403                                        <p><?php _e( 'You have successfully created your account! To begin using this site you will need to activate your account via the email we have just sent to your address.', 'buddypress' ); ?></p>
    395404                                <?php else : ?>
    396405                                        <p><?php _e( 'You have successfully created your account! Please log in using the username and password you have just created.', 'buddypress' ); ?></p>
  • src/bp-templates/bp-nouveau/includes/functions.php

    diff --git src/bp-templates/bp-nouveau/includes/functions.php src/bp-templates/bp-nouveau/includes/functions.php
    index 3d85eace9..5faa6b0f9 100644
    function bp_nouveau_get_user_feedback( $feedback_id = '' ) { 
    11221122        /*
    11231123         * Adjust some messages to the context.
    11241124         */
    1125         if ( 'completed-confirmation' === $feedback_id && bp_registration_needs_activation() ) {
     1125        if ( 'completed-confirmation' === $feedback_id && bp_get_membership_requests_required() ) {
     1126                $feedback_messages['completed-confirmation']['message'] = __( 'You have successfully submitted your membership request! Our site moderators will review your submission and send you an activation email if your request is approved.', 'buddypress' );
     1127        } elseif ( 'completed-confirmation' === $feedback_id && bp_registration_needs_activation() ) {
    11261128                $feedback_messages['completed-confirmation']['message'] = __( 'You have successfully created your account! To begin using this site you will need to activate your account via the email we have just sent to your address.', 'buddypress' );
    11271129        } elseif ( 'member-notifications-none' === $feedback_id ) {
    11281130                $is_myprofile = bp_is_my_profile();