<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[BuddyPress][13167] trunk/src: Add key membership request functionality.</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { white-space: pre-line; overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta" style="font-size: 105%">
<dt style="float: left; width: 6em; font-weight: bold">Revision</dt> <dd><a style="font-weight: bold" href="http://buddypress.trac.wordpress.org/changeset/13167">13167</a><script type="application/ld+json">{"@context":"http://schema.org","@type":"EmailMessage","description":"Review this Commit","action":{"@type":"ViewAction","url":"http://buddypress.trac.wordpress.org/changeset/13167","name":"Review Commit"}}</script></dd>
<dt style="float: left; width: 6em; font-weight: bold">Author</dt> <dd>dcavins</dd>
<dt style="float: left; width: 6em; font-weight: bold">Date</dt> <dd>2021-12-10 16:14:25 +0000 (Fri, 10 Dec 2021)</dd>
</dl>

<pre style='padding-left: 1em; margin: 2em 0; border-left: 2px solid #ccc; line-height: 1.25; font-size: 105%; font-family: sans-serif'>Add key membership request functionality.

When membership requests are active, interrupt the
activation process by not sending the activation mail
upon submission of the registration form. This allows the
site admin an opportunity to look over the request and
send the activation email manually.

See <a href="http://buddypress.trac.wordpress.org/ticket/8582">#8582</a>.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunksrcbpcorebpcorefiltersphp">trunk/src/bp-core/bp-core-filters.php</a></li>
<li><a href="#trunksrcbpmembersclassesclassbpmemberscomponentphp">trunk/src/bp-members/classes/class-bp-members-component.php</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunksrcbpmembersbpmembersmembershiprequestsphp">trunk/src/bp-members/bp-members-membership-requests.php</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunksrcbpcorebpcorefiltersphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/bp-core/bp-core-filters.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/bp-core/bp-core-filters.php     2021-12-10 16:14:11 UTC (rev 13166)
+++ trunk/src/bp-core/bp-core-filters.php       2021-12-10 16:14:25 UTC (rev 13167)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -461,6 +461,12 @@
</span><span class="cx" style="display: block; padding: 0 10px">  * @return bool              Returns false to stop original WPMU function from continuing.
</span><span class="cx" style="display: block; padding: 0 10px">  */
</span><span class="cx" style="display: block; padding: 0 10px"> function bp_core_activation_signup_blog_notification( $domain, $path, $title, $user, $user_email, $key ) {
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+        $is_signup_resend = false;
+       if ( is_admin() && buddypress()->members->admin->signups_page == get_current_screen()->id ) {
+               // The admin is just approving/sending/resending the verification email.
+               $is_signup_resend = true;
+       }
+
</ins><span class="cx" style="display: block; padding: 0 10px">         $args = array(
</span><span class="cx" style="display: block; padding: 0 10px">                'tokens' => array(
</span><span class="cx" style="display: block; padding: 0 10px">                        'activate-site.url' => esc_url( bp_get_activation_page() . '?key=' . urlencode( $key ) ),
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -481,7 +487,22 @@
</span><span class="cx" style="display: block; padding: 0 10px">                }
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        bp_send_email( 'core-user-registration-with-blog', array( array( $user_email => $salutation ) ), $args );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ /**
+        * Filters if BuddyPress should send an activation key for a new multisite signup.
+        *
+        * @since 10.0.0
+        *
+        * @param string $user             The user's login name.
+        * @param string $user_email       The user's email address.
+        * @param string $key              The activation key created in wpmu_signup_blog().
+        * @param bool   $is_signup_resend Is the site admin sending this email?
+        * @param string $domain           The new blog domain.
+        * @param string $path             The new blog path.
+        * @param string $title            The site title.
+        */
+       if ( apply_filters( 'bp_core_signup_send_activation_key_multisite_blog', true, $user, $user_email, $key, $is_signup_resend, $domain, $path, $title ) ) {
+               bp_send_email( 'core-user-registration-with-blog', array( array( $user_email => $salutation ) ), $args );
+       }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        // Return false to stop the original WPMU function from continuing.
</span><span class="cx" style="display: block; padding: 0 10px">        return false;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -502,6 +523,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">  * @return false|string Returns false to stop original WPMU function from continuing.
</span><span class="cx" style="display: block; padding: 0 10px">  */
</span><span class="cx" style="display: block; padding: 0 10px"> function bp_core_activation_signup_user_notification( $user, $user_email, $key, $meta ) {
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+        $is_signup_resend = false;
</ins><span class="cx" style="display: block; padding: 0 10px">         if ( is_admin() ) {
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                // If the user is created from the WordPress Add User screen, don't send BuddyPress signup notifications.
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -515,17 +537,21 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                return $user;
</span><span class="cx" style="display: block; padding: 0 10px">                        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                /*
-                * There can be a case where the user was created without the skip confirmation
-                * And the super admin goes in pending accounts to resend it. In this case, as the
-                * meta['password'] is not set, the activation url must be WordPress one.
-                */
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         // The site admin is approving/resending from the "manage signups" screen.
</ins><span class="cx" style="display: block; padding: 0 10px">                 } elseif ( buddypress()->members->admin->signups_page == get_current_screen()->id ) {
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                        /*
+                        * There can be a case where the user was created without the skip confirmation
+                        * And the super admin goes in pending accounts to resend it. In this case, as the
+                        * meta['password'] is not set, the activation url must be WordPress one.
+                        */
</ins><span class="cx" style="display: block; padding: 0 10px">                         $is_hashpass_in_meta = maybe_unserialize( $meta );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                        if ( empty( $is_hashpass_in_meta['password'] ) ) {
</span><span class="cx" style="display: block; padding: 0 10px">                                return $user;
</span><span class="cx" style="display: block; padding: 0 10px">                        }
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+                       // Or the admin is just approving/sending/resending the verification email.
+                       $is_signup_resend = true;
</ins><span class="cx" style="display: block; padding: 0 10px">                 }
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -550,8 +576,21 @@
</span><span class="cx" style="display: block; padding: 0 10px">                        'user.id'      => $user_id,
</span><span class="cx" style="display: block; padding: 0 10px">                ),
</span><span class="cx" style="display: block; padding: 0 10px">        );
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        bp_send_email( 'core-user-registration', array( array( $user_email => $salutation ) ), $args );
</del><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+        /**
+        * Filters if BuddyPress should send an activation key for a new multisite signup.
+        *
+        * @since 10.0.0
+        *
+        * @param string $user             The user's login name.
+        * @param string $user_email       The user's email address.
+        * @param string $key              The activation key created in wpmu_signup_blog().
+        * @param bool   $is_signup_resend Is the site admin sending this email?
+        */
+       if ( apply_filters( 'bp_core_signup_send_activation_key_multisite', true, $user, $user_email, $key, $is_signup_resend ) ) {
+               bp_send_email( 'core-user-registration', array( array( $user_email => $salutation ) ), $args );
+       }
+
</ins><span class="cx" style="display: block; padding: 0 10px">         // Return false to stop the original WPMU function from continuing.
</span><span class="cx" style="display: block; padding: 0 10px">        return false;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span></span></pre></div>
<a id="trunksrcbpmembersbpmembersmembershiprequestsphp"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: trunk/src/bp-members/bp-members-membership-requests.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/bp-members/bp-members-membership-requests.php                           (rev 0)
+++ trunk/src/bp-members/bp-members-membership-requests.php     2021-12-10 16:14:25 UTC (rev 13167)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,137 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+/**
+ * BuddyPress Membership Requests
+ *
+ * @package BuddyPress
+ * @subpackage MembersMembershipRequest
+ * @since 10.0.0
+ */
+
+// Exit if accessed directly.
+defined( 'ABSPATH' ) || exit;
+
+/**
+ * Single site: When a user creates a membership request,
+ * prevent the sending of the activation email so that
+ * the site admins can send it manually.
+ *
+ * @since 10.0.0
+ *
+ * @param bool   $send           Whether or not to send the activation key.
+ * @param int    $user_id        User ID to send activation key to.
+ * @param string $user_email     User email to send activation key to.
+ * @param string $activation_key Activation key to be sent.
+ * @param array  $usermeta       Miscellaneous metadata about the user (blog-specific
+ *                               signup data, xprofile data, etc).
+ * @return bool Whether or not to send the activation key.
+ */
+function bp_members_membership_requests_cancel_activation_email( $send, $user_id = 0, $user_email = '', $activation_key = '', $usermeta = array() ) {
+
+       $details = array(
+               'user_id'        => $user_id,
+               'user_email'     => $user_email,
+               'activation_key' => $activation_key,
+               'usermeta'       => $usermeta,
+       );
+
+       /**
+        * Allow some membership requests to be approved immediately.
+        * For example, you might want to approve all requests
+        * coming from users with certain email address domains.
+        * If `true` is returned the activation email will be sent to the user.
+        *
+        * @since 10.0.0
+        *
+        * @param bool  $send    Whether or not this membership request should be approved
+        *                       immediately and the activation email sent.
+        *                       Default is `false` meaning that the request should be
+        *                       manually approved by a site admin.
+        * @param array $details The details of the request.
+        */
+       $send = apply_filters( 'bp_members_membership_requests_bypass_manual_approval', false, $details );
+
+       // If the registration process has been interrupted, this is a new membership request.
+       if ( ! $send ) {
+               $signup = bp_members_get_signup_by( 'activation_key', $activation_key );
+
+               /**
+                * Fires when a site membership request has been created and is pending.
+                *
+                * @since 10.0.0
+                *
+                * @param BP_Signup $signup  The signup object that has been created.
+                * @param array     $details The details of the request.
+                */
+               do_action( 'bp_members_membership_request_submitted', $signup, $details );
+       }
+
+       return $send;
+}
+add_filter( 'bp_core_signup_send_activation_key', 'bp_members_membership_requests_cancel_activation_email', 10, 5 );
+
+/**
+ * WP Multisite: When a user creates a membership request,
+ * prevent the sending of the activation email so that
+ * the site admins can send it manually.
+ *
+ * @since 10.0.0
+ *
+ * @param bool   $send             Whether or not to send the activation key.
+ * @param string $user_login       User login name.
+ * @param string $user_email       User email address.
+ * @param string $activation_key   Activation key created in wpmu_signup_user().
+ * @param bool   $is_signup_resend Is the site admin sending this email?
+ * @return bool Whether or not to send the activation key.
+ */
+function bp_members_membership_requests_cancel_activation_email_multisite( $send = true, $user_login = '', $user_email = '', $activation_key = '', $is_signup_resend = false ) {
+
+       $details = array(
+               'user_login'       => $user_login,
+               'user_email'       => $user_email,
+               'activation_key'   => $activation_key,
+               'is_signup_resend' => $is_signup_resend,
+       );
+
+       // Allow the site admin to send/resend approval emails.
+       if ( $is_signup_resend ) {
+               $to_send = true;
+       } else {
+               $to_send = false;
+       }
+
+       /**
+        * Allow some membership requests to be approved immediately.
+        * For example, you might want to approve all requests
+        * coming from users with certain email address domains.
+        * If `true` is returned the activation email will be sent to the user.
+        *
+        * @since 10.0.0
+        *
+        * @param bool  $to_send Whether or not this membership request should be approved
+        *                       immediately and the activation email sent.
+        *                       Default is `false` meaning that the request should be
+        *                       manually approved by a site admin.
+        * @param array $details The details of the request.
+        */
+       $send = apply_filters( 'bp_members_membership_requests_bypass_manual_approval_multisite', $to_send, $details );
+
+       // If the registration process has been interrupted, this is a new membership request.
+       if ( ! $send ) {
+               $signup = bp_members_get_signup_by( 'activation_key', $activation_key );
+
+               /**
+                * Fires when a site membership request has been created and is pending.
+                *
+                * @since 10.0.0
+                *
+                * @param BP_Signup $signup  The signup object that has been created.
+                * @param array     $details The details of the request.
+                */
+               do_action( 'bp_members_membership_request_submitted', $signup, $details );
+       }
+
+       return $send;
+}
+add_filter( 'bp_core_signup_send_activation_key_multisite', 'bp_members_membership_requests_cancel_activation_email_multisite', 10, 5 );
+add_filter( 'bp_core_signup_send_activation_key_multisite_blog', 'bp_members_membership_requests_cancel_activation_email_multisite', 10, 5 );
+
</ins></span></pre></div>
<a id="trunksrcbpmembersclassesclassbpmemberscomponentphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/bp-members/classes/class-bp-members-component.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/bp-members/classes/class-bp-members-component.php       2021-12-10 16:14:11 UTC (rev 13166)
+++ trunk/src/bp-members/classes/class-bp-members-component.php 2021-12-10 16:14:25 UTC (rev 13167)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -40,7 +40,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                        array(
</span><span class="cx" style="display: block; padding: 0 10px">                                'adminbar_myaccount_order' => 20,
</span><span class="cx" style="display: block; padding: 0 10px">                                'search_query_arg'         => 'members_search',
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                'features'                 => array( 'invitations' )
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         'features'                 => array( 'invitations', 'membership_requests' ),
</ins><span class="cx" style="display: block; padding: 0 10px">                         )
</span><span class="cx" style="display: block; padding: 0 10px">                );
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -74,6 +74,19 @@
</span><span class="cx" style="display: block; padding: 0 10px">                        $includes[] = 'activity';
</span><span class="cx" style="display: block; padding: 0 10px">                }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                /**
+                * Duplicate bp_get_membership_requests_required() and
+                * bp_get_signup_allowed() logic here,
+                * because those functions are not available yet.
+                * The `bp_get_signup_allowed` filter is documented in
+                * bp-members/bp-members-template.php.
+                */
+               $signup_allowed = apply_filters( 'bp_get_signup_allowed', (bool) bp_get_option( 'users_can_register' ) );
+               $membership_requests_enabled = (bool) bp_get_option( 'bp-enable-membership-requests' );
+               if ( bp_is_active( 'members', 'membership_requests' ) && ! $signup_allowed && $membership_requests_enabled ) {
+                       $includes[] = 'membership-requests';
+               }
+
</ins><span class="cx" style="display: block; padding: 0 10px">                 // Include these only if in admin.
</span><span class="cx" style="display: block; padding: 0 10px">                if ( is_admin() ) {
</span><span class="cx" style="display: block; padding: 0 10px">                        $includes[] = 'admin';
</span></span></pre>
</div>
</div>

</body>
</html>