/**
 * Send notifications related to the acceptance of a friendship request.
 *
 * When a friendship request is accepted, an email and a BP notification are
 * sent to the user who requested the friendship ($initiator_id).
 *
 * @since 1.0.0
 *
 * @param int $friendship_id ID of the friendship object.
 * @param int $initiator_id  ID of the user who initiated the request.
 * @param int $friend_id     ID of the request recipient.
 */
function friends_notification_accepted_request($friendship_id, $initiator_id, $friend_id)
{
    if ('no' == bp_get_user_meta((int) $initiator_id, 'notification_friends_friendship_accepted', true)) {
        return;
    }
    $args = array('tokens' => array('friend.id' => $friend_id, 'friendship.url' => esc_url(bp_core_get_user_domain($friend_id)), 'friend.name' => bp_core_get_user_displayname($friend_id), 'friendship.id' => $friendship_id, 'initiator.id' => $initiator_id));
    bp_send_email('friends-request-accepted', $initiator_id, $args);
}
/**
 * Email message recipients to alert them of a new unread private message.
 *
 * @since 1.0.0
 *
 * @param array|BP_Messages_Message $raw_args {
 *     Array of arguments. Also accepts a BP_Messages_Message object.
 *     @type array  $recipients    User IDs of recipients.
 *     @type string $email_subject Subject line of message.
 *     @type string $email_content Content of message.
 *     @type int    $sender_id     User ID of sender.
 * }
 */
function messages_notification_new_message($raw_args = array())
{
    if (is_object($raw_args)) {
        $args = (array) $raw_args;
    } else {
        $args = $raw_args;
    }
    // These should be extracted below.
    $recipients = array();
    $email_subject = $email_content = '';
    $sender_id = 0;
    // Barf.
    extract($args);
    if (empty($recipients)) {
        return;
    }
    $sender_name = bp_core_get_user_displayname($sender_id);
    // Send an email to each recipient.
    foreach ($recipients as $recipient) {
        if ($sender_id == $recipient->user_id || 'no' == bp_get_user_meta($recipient->user_id, 'notification_messages_new_message', true)) {
            continue;
        }
        // User data and links.
        $ud = get_userdata($recipient->user_id);
        if (empty($ud)) {
            continue;
        }
        $args = array('tokens' => array('usermessage' => wp_strip_all_tags(stripslashes($message)), 'message.url' => esc_url(bp_core_get_user_domain($recipient->user_id) . bp_get_messages_slug() . '/view/' . $thread_id . '/'), 'sender.name' => $sender_name, 'usersubject' => sanitize_text_field(stripslashes($subject))));
        bp_send_email('messages-unread', $ud, $args);
    }
    /**
     * Fires after the sending of a new message email notification.
     *
     * @since 1.5.0
     * @deprecated 2.5.0 Use the filters in BP_Email.
     *                   $email_subject and $email_content arguments unset and deprecated.
     *
     * @param array  $recipients    User IDs of recipients.
     * @param string $email_subject Deprecated in 2.5; now an empty string.
     * @param string $email_content Deprecated in 2.5; now an empty string.
     * @param array  $args          Array of originally provided arguments.
     */
    do_action('bp_messages_sent_notification_email', $recipients, '', '', $args);
}
/**
 * Send activation email to a newly registered user.
 *
 * @since 1.2.2
 * @since 2.5.0 Add the $user_login parameter.
 *
 * @param int|bool $user_id    ID of the new user, false if BP_SIGNUPS_SKIP_USER_CREATION is true.
 * @param string   $user_email Email address of the new user.
 * @param string   $key        Activation key.
 * @param string   $user_login Optional. The user login name.
 */
function bp_core_signup_send_validation_email($user_id, $user_email, $key, $user_login = '')
{
    $args = array('tokens' => array('activate.url' => esc_url(trailingslashit(bp_get_activation_page()) . "{$key}/"), 'key' => $key, 'user.email' => $user_email, 'user.id' => $user_id));
    if ($user_id) {
        $to = $user_id;
    } else {
        $to = array(array($user_email => $user_login));
    }
    bp_send_email('core-user-registration', $to, $args);
}
/**
 * Notify a member they have been invited to a group.
 *
 * @since 1.0.0
 *
 * @param BP_Groups_Group  $group           Group object.
 * @param BP_Groups_Member $member          Member object.
 * @param int              $inviter_user_id ID of the user who sent the invite.
 */
function groups_notification_group_invites(&$group, &$member, $inviter_user_id)
{
    // Bail if member has already been invited.
    if (!empty($member->invite_sent)) {
        return;
    }
    // @todo $inviter_ud may be used for caching, test without it
    $inviter_ud = bp_core_get_core_userdata($inviter_user_id);
    $invited_user_id = $member->user_id;
    // Trigger a BuddyPress Notification.
    if (bp_is_active('notifications')) {
        bp_notifications_add_notification(array('user_id' => $invited_user_id, 'item_id' => $group->id, 'component_name' => buddypress()->groups->id, 'component_action' => 'group_invite'));
    }
    // Bail if member opted out of receiving this email.
    if ('no' === bp_get_user_meta($invited_user_id, 'notification_groups_invite', true)) {
        return;
    }
    $invited_link = bp_core_get_user_domain($invited_user_id) . bp_get_groups_slug();
    $unsubscribe_args = array('user_id' => $invited_user_id, 'notification_type' => 'groups-invitation');
    $args = array('tokens' => array('group' => $group, 'group.url' => bp_get_group_permalink($group), 'group.name' => $group->name, 'inviter.name' => bp_core_get_userlink($inviter_user_id, true, false, true), 'inviter.url' => bp_core_get_user_domain($inviter_user_id), 'inviter.id' => $inviter_user_id, 'invites.url' => esc_url($invited_link . '/invites/'), 'unsubscribe' => esc_url(bp_email_get_unsubscribe_link($unsubscribe_args))));
    bp_send_email('groups-invitation', (int) $invited_user_id, $args);
}
/**
 * Send email and BP notifications when an activity item receives a comment.
 *
 * @since 1.2.0
 * @since 2.5.0 Updated to use new email APIs.
 *
 * @uses bp_get_user_meta()
 * @uses bp_core_get_user_displayname()
 * @uses bp_activity_get_permalink()
 * @uses bp_core_get_user_domain()
 * @uses bp_get_settings_slug()
 * @uses bp_activity_filter_kses()
 * @uses bp_core_get_core_userdata()
 * @uses wp_specialchars_decode()
 * @uses get_blog_option()
 * @uses bp_get_root_blog_id()
 * @uses apply_filters() To call the 'bp_activity_new_comment_notification_to' hook.
 * @uses apply_filters() To call the 'bp_activity_new_comment_notification_subject' hook.
 * @uses apply_filters() To call the 'bp_activity_new_comment_notification_message' hook.
 * @uses wp_mail()
 * @uses do_action() To call the 'bp_activity_sent_reply_to_update_email' hook.
 * @uses apply_filters() To call the 'bp_activity_new_comment_notification_comment_author_to' hook.
 * @uses apply_filters() To call the 'bp_activity_new_comment_notification_comment_author_subject' hook.
 * @uses apply_filters() To call the 'bp_activity_new_comment_notification_comment_author_message' hook.
 * @uses do_action() To call the 'bp_activity_sent_reply_to_reply_email' hook.
 *
 * @param int   $comment_id   The comment id.
 * @param int   $commenter_id The ID of the user who posted the comment.
 * @param array $params       {@link bp_activity_new_comment()}.
 */
function bp_activity_new_comment_notification($comment_id = 0, $commenter_id = 0, $params = array())
{
    $original_activity = new BP_Activity_Activity($params['activity_id']);
    $poster_name = bp_core_get_user_displayname($commenter_id);
    $thread_link = bp_activity_get_permalink($params['activity_id']);
    remove_filter('bp_get_activity_content_body', 'convert_smilies');
    remove_filter('bp_get_activity_content_body', 'wpautop');
    remove_filter('bp_get_activity_content_body', 'bp_activity_truncate_entry', 5);
    /** This filter is documented in bp-activity/bp-activity-template.php */
    $content = apply_filters('bp_get_activity_content_body', $params['content']);
    add_filter('bp_get_activity_content_body', 'convert_smilies');
    add_filter('bp_get_activity_content_body', 'wpautop');
    add_filter('bp_get_activity_content_body', 'bp_activity_truncate_entry', 5);
    if ($original_activity->user_id != $commenter_id && 'no' != bp_get_user_meta($original_activity->user_id, 'notification_activity_new_reply', true)) {
        $args = array('tokens' => array('comment.id' => $comment_id, 'commenter.id' => $commenter_id, 'usermessage' => wp_strip_all_tags($content), 'original_activity.user_id' => $original_activity->user_id, 'poster.name' => $poster_name, 'thread.url' => esc_url($thread_link)));
        bp_send_email('activity-comment', $original_activity->user_id, $args);
    }
    /*
     * If this is a reply to another comment, send an email notification to the
     * author of the immediate parent comment.
     */
    if (empty($params['parent_id']) || $params['activity_id'] == $params['parent_id']) {
        return;
    }
    $parent_comment = new BP_Activity_Activity($params['parent_id']);
    if ($parent_comment->user_id != $commenter_id && $original_activity->user_id != $parent_comment->user_id && 'no' != bp_get_user_meta($parent_comment->user_id, 'notification_activity_new_reply', true)) {
        $args = array('tokens' => array('comment.id' => $comment_id, 'commenter.id' => $commenter_id, 'usermessage' => wp_strip_all_tags($content), 'parent-comment-user.id' => $parent_comment->user_id, 'poster.name' => $poster_name, 'thread.url' => esc_url($thread_link)));
        bp_send_email('activity-comment-author', $parent_comment->user_id, $args);
    }
}
/**
 * Send email and BP notifications when an activity item receives a comment.
 *
 * @since 1.2.0
 * @since 2.5.0 Updated to use new email APIs.
 *
 * @param int   $comment_id   The comment id.
 * @param int   $commenter_id The ID of the user who posted the comment.
 * @param array $params       {@link bp_activity_new_comment()}.
 */
function bp_activity_new_comment_notification($comment_id = 0, $commenter_id = 0, $params = array())
{
    $original_activity = new BP_Activity_Activity($params['activity_id']);
    $poster_name = bp_core_get_user_displayname($commenter_id);
    $thread_link = bp_activity_get_permalink($params['activity_id']);
    remove_filter('bp_get_activity_content_body', 'convert_smilies');
    remove_filter('bp_get_activity_content_body', 'wpautop');
    remove_filter('bp_get_activity_content_body', 'bp_activity_truncate_entry', 5);
    /** This filter is documented in bp-activity/bp-activity-template.php */
    $content = apply_filters('bp_get_activity_content_body', $params['content']);
    add_filter('bp_get_activity_content_body', 'convert_smilies');
    add_filter('bp_get_activity_content_body', 'wpautop');
    add_filter('bp_get_activity_content_body', 'bp_activity_truncate_entry', 5);
    if ($original_activity->user_id != $commenter_id) {
        // Send an email if the user hasn't opted-out.
        if ('no' != bp_get_user_meta($original_activity->user_id, 'notification_activity_new_reply', true)) {
            $unsubscribe_args = array('user_id' => $original_activity->user_id, 'notification_type' => 'activity-comment');
            $args = array('tokens' => array('comment.id' => $comment_id, 'commenter.id' => $commenter_id, 'usermessage' => wp_strip_all_tags($content), 'original_activity.user_id' => $original_activity->user_id, 'poster.name' => $poster_name, 'thread.url' => esc_url($thread_link), 'unsubscribe' => esc_url(bp_email_get_unsubscribe_link($unsubscribe_args))));
            bp_send_email('activity-comment', $original_activity->user_id, $args);
        }
        /**
         * Fires at the point that notifications should be sent for activity comments.
         *
         * @since 2.6.0
         *
         * @param BP_Activity_Activity $original_activity The original activity.
         * @param int                  $comment_id        ID for the newly received comment.
         * @param int                  $commenter_id      ID of the user who made the comment.
         * @param array                $params            Arguments used with the original activity comment.
         */
        do_action('bp_activity_sent_reply_to_update_notification', $original_activity, $comment_id, $commenter_id, $params);
    }
    /*
     * If this is a reply to another comment, send an email notification to the
     * author of the immediate parent comment.
     */
    if (empty($params['parent_id']) || $params['activity_id'] == $params['parent_id']) {
        return;
    }
    $parent_comment = new BP_Activity_Activity($params['parent_id']);
    if ($parent_comment->user_id != $commenter_id && $original_activity->user_id != $parent_comment->user_id) {
        // Send an email if the user hasn't opted-out.
        if ('no' != bp_get_user_meta($parent_comment->user_id, 'notification_activity_new_reply', true)) {
            $unsubscribe_args = array('user_id' => $parent_comment->user_id, 'notification_type' => 'activity-comment-author');
            $args = array('tokens' => array('comment.id' => $comment_id, 'commenter.id' => $commenter_id, 'usermessage' => wp_strip_all_tags($content), 'parent-comment-user.id' => $parent_comment->user_id, 'poster.name' => $poster_name, 'thread.url' => esc_url($thread_link), 'unsubscribe' => esc_url(bp_email_get_unsubscribe_link($unsubscribe_args))));
            bp_send_email('activity-comment-author', $parent_comment->user_id, $args);
        }
        /**
         * Fires at the point that notifications should be sent for comments on activity replies.
         *
         * @since 2.6.0
         *
         * @param BP_Activity_Activity $parent_comment The parent activity.
         * @param int                  $comment_id     ID for the newly received comment.
         * @param int                  $commenter_id   ID of the user who made the comment.
         * @param array                $params         Arguments used with the original activity comment.
         */
        do_action('bp_activity_sent_reply_to_reply_notification', $parent_comment, $comment_id, $commenter_id, $params);
    }
}
/**
 * Handles the changing and saving of user email addresses and passwords.
 *
 * We do quite a bit of logic and error handling here to make sure that users
 * do not accidentally lock themselves out of their accounts. We also try to
 * provide as accurate of feedback as possible without exposing anyone else's
 * information to them.
 *
 * Special considerations are made for super admins that are able to edit any
 * users accounts already, without knowing their existing password.
 *
 * @since 1.6.0
 *
 * @global BuddyPress $bp
 */
function bp_settings_action_general()
{
    // Bail if not a POST action.
    if ('POST' !== strtoupper($_SERVER['REQUEST_METHOD'])) {
        return;
    }
    // Bail if no submit action.
    if (!isset($_POST['submit'])) {
        return;
    }
    // Bail if not in settings.
    if (!bp_is_settings_component() || !bp_is_current_action('general')) {
        return;
    }
    // 404 if there are any additional action variables attached
    if (bp_action_variables()) {
        bp_do_404();
        return;
    }
    // Define local defaults
    $bp = buddypress();
    // The instance
    $email_error = false;
    // invalid|blocked|taken|empty|nochange
    $pass_error = false;
    // invalid|mismatch|empty|nochange
    $pass_changed = false;
    // true if the user changes their password
    $email_changed = false;
    // true if the user changes their email
    $feedback_type = 'error';
    // success|error
    $feedback = array();
    // array of strings for feedback.
    // Nonce check.
    check_admin_referer('bp_settings_general');
    // Validate the user again for the current password when making a big change.
    if (is_super_admin() || !empty($_POST['pwd']) && wp_check_password($_POST['pwd'], $bp->displayed_user->userdata->user_pass, bp_displayed_user_id())) {
        $update_user = get_userdata(bp_displayed_user_id());
        /* Email Change Attempt ******************************************/
        if (!empty($_POST['email'])) {
            // What is missing from the profile page vs signup -
            // let's double check the goodies.
            $user_email = sanitize_email(esc_html(trim($_POST['email'])));
            $old_user_email = $bp->displayed_user->userdata->user_email;
            // User is changing email address.
            if ($old_user_email != $user_email) {
                // Run some tests on the email address.
                $email_checks = bp_core_validate_email_address($user_email);
                if (true !== $email_checks) {
                    if (isset($email_checks['invalid'])) {
                        $email_error = 'invalid';
                    }
                    if (isset($email_checks['domain_banned']) || isset($email_checks['domain_not_allowed'])) {
                        $email_error = 'blocked';
                    }
                    if (isset($email_checks['in_use'])) {
                        $email_error = 'taken';
                    }
                }
                // Store a hash to enable email validation.
                if (false === $email_error) {
                    $hash = wp_hash($_POST['email']);
                    $pending_email = array('hash' => $hash, 'newemail' => $user_email);
                    bp_update_user_meta(bp_displayed_user_id(), 'pending_email_change', $pending_email);
                    $verify_link = bp_displayed_user_domain() . bp_get_settings_slug() . '/?verify_email_change=' . $hash;
                    // Send the verification email.
                    $args = array('tokens' => array('displayname' => bp_core_get_user_displayname(bp_displayed_user_id()), 'old-user.email' => $old_user_email, 'user.email' => $user_email, 'verify.url' => esc_url($verify_link)));
                    bp_send_email('settings-verify-email-change', bp_displayed_user_id(), $args);
                    // We mark that the change has taken place so as to ensure a
                    // success message, even though verification is still required.
                    $_POST['email'] = $update_user->user_email;
                    $email_changed = true;
                }
                // No change.
            } else {
                $email_error = false;
            }
            // Email address cannot be empty.
        } else {
            $email_error = 'empty';
        }
        /* Password Change Attempt ***************************************/
        if (!empty($_POST['pass1']) && !empty($_POST['pass2'])) {
            if ($_POST['pass1'] == $_POST['pass2'] && !strpos(" " . $_POST['pass1'], "\\")) {
                // Password change attempt is successful.
                if (!empty($_POST['pwd']) && $_POST['pwd'] != $_POST['pass1'] || is_super_admin()) {
                    $update_user->user_pass = $_POST['pass1'];
                    $pass_changed = true;
                    // The new password is the same as the current password.
                } else {
                    $pass_error = 'same';
                }
                // Password change attempt was unsuccessful.
            } else {
                $pass_error = 'mismatch';
            }
            // Both password fields were empty.
        } elseif (empty($_POST['pass1']) && empty($_POST['pass2'])) {
            $pass_error = false;
            // One of the password boxes was left empty.
        } elseif (empty($_POST['pass1']) && !empty($_POST['pass2']) || !empty($_POST['pass1']) && empty($_POST['pass2'])) {
            $pass_error = 'empty';
        }
        // The structure of the $update_user object changed in WP 3.3, but
        // wp_update_user() still expects the old format.
        if (isset($update_user->data) && is_object($update_user->data)) {
            $update_user = $update_user->data;
            $update_user = get_object_vars($update_user);
            // Unset the password field to prevent it from emptying out the
            // user's user_pass field in the database.
            // @see wp_update_user().
            if (false === $pass_changed) {
                unset($update_user['user_pass']);
            }
        }
        // Clear cached data, so that the changed settings take effect
        // on the current page load.
        if (false === $email_error && false === $pass_error && wp_update_user($update_user)) {
            wp_cache_delete('bp_core_userdata_' . bp_displayed_user_id(), 'bp');
            $bp->displayed_user->userdata = bp_core_get_core_userdata(bp_displayed_user_id());
        }
        // Password Error.
    } else {
        $pass_error = 'invalid';
    }
    // Email feedback.
    switch ($email_error) {
        case 'invalid':
            $feedback['email_invalid'] = __('That email address is invalid. Check the formatting and try again.', 'buddypress');
            break;
        case 'blocked':
            $feedback['email_blocked'] = __('That email address is currently unavailable for use.', 'buddypress');
            break;
        case 'taken':
            $feedback['email_taken'] = __('That email address is already taken.', 'buddypress');
            break;
        case 'empty':
            $feedback['email_empty'] = __('Email address cannot be empty.', 'buddypress');
            break;
        case false:
            // No change.
            break;
    }
    // Password feedback.
    switch ($pass_error) {
        case 'invalid':
            $feedback['pass_error'] = __('Your current password is invalid.', 'buddypress');
            break;
        case 'mismatch':
            $feedback['pass_mismatch'] = __('The new password fields did not match.', 'buddypress');
            break;
        case 'empty':
            $feedback['pass_empty'] = __('One of the password fields was empty.', 'buddypress');
            break;
        case 'same':
            $feedback['pass_same'] = __('The new password must be different from the current password.', 'buddypress');
            break;
        case false:
            // No change.
            break;
    }
    // No errors so show a simple success message.
    if ((false === $email_error || false == $pass_error) && (true === $pass_changed || true === $email_changed)) {
        $feedback[] = __('Your settings have been saved.', 'buddypress');
        $feedback_type = 'success';
        // Some kind of errors occurred.
    } elseif ((false === $email_error || false === $pass_error) && (false === $pass_changed || false === $email_changed)) {
        if (bp_is_my_profile()) {
            $feedback['nochange'] = __('No changes were made to your account.', 'buddypress');
        } else {
            $feedback['nochange'] = __('No changes were made to this account.', 'buddypress');
        }
    }
    // Set the feedback.
    bp_core_add_message(implode("\n", $feedback), $feedback_type);
    /**
     * Fires after the general settings have been saved, and before redirect.
     *
     * @since 1.5.0
     */
    do_action('bp_core_general_settings_after_save');
    // Redirect to prevent issues with browser back button.
    bp_core_redirect(trailingslashit(bp_displayed_user_domain() . bp_get_settings_slug() . '/general'));
}
/**
 * Notify new users of a successful registration (without blog).
 *
 * @since 1.0.0
 *
 * @see wpmu_signup_user_notification() for a full description of params.
 *
 * @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_user().
 * @param array  $meta       By default, an empty array.
 * @return bool|string       Returns false to stop original WPMU function from continuing.
 */
function bp_core_activation_signup_user_notification($user, $user_email, $key, $meta)
{
    if (is_admin()) {
        // If the user is created from the WordPress Add User screen, don't send BuddyPress signup notifications.
        if (in_array(get_current_screen()->id, array('user', 'user-network'))) {
            // If the Super Admin want to skip confirmation email.
            if (isset($_POST['noconfirmation']) && is_super_admin()) {
                return false;
                // WordPress will manage the signup process.
            } else {
                return $user;
            }
            /*
             * 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.
             */
        } elseif (buddypress()->members->admin->signups_page == get_current_screen()->id) {
            $is_hashpass_in_meta = maybe_unserialize($meta);
            if (empty($is_hashpass_in_meta['password'])) {
                return $user;
            }
        }
    }
    $user_id = 0;
    $user_object = get_user_by('login', $user);
    if ($user_object) {
        $user_id = $user_object->ID;
    }
    $args = array('tokens' => array('activate.url' => esc_url(trailingslashit(bp_get_activation_page()) . "{$key}/"), 'key' => $key, 'user.email' => $user_email, 'user.id' => $user_id));
    bp_send_email('core-user-registration', array(array($user_email => $user)), $args);
    // Return false to stop the original WPMU function from continuing.
    return false;
}
 public function test_sending_email()
 {
     require_once BP_PLUGIN_DIR . '/bp-core/admin/bp-core-admin-schema.php';
     bp_core_install_emails();
     $user1 = get_user_by('id', $this->u1);
     $result = bp_send_email('core-user-registration', $this->u1, array('tokens' => array('activate.url' => 'http://example.com', 'key' => '123', 'user.email' => $user1->user_email, 'user.id' => $this->u1)));
     $this->assertTrue($result);
 }