| 3375 | | function bp_email_get_type_schema() { |
| 3376 | | return array( |
| 3377 | | 'activity-comment' => __( 'A member has replied to an activity update that the recipient posted.', 'buddypress' ), |
| 3378 | | 'activity-comment-author' => __( 'A member has replied to a comment on an activity update that the recipient posted.', 'buddypress' ), |
| 3379 | | 'activity-at-message' => __( 'Recipient was mentioned in an activity update.', 'buddypress' ), |
| 3380 | | 'groups-at-message' => __( 'Recipient was mentioned in a group activity update.', 'buddypress' ), |
| 3381 | | 'core-user-registration' => __( 'Recipient has registered for an account.', 'buddypress' ), |
| 3382 | | 'core-user-registration-with-blog' => __( 'Recipient has registered for an account and site.', 'buddypress' ), |
| 3383 | | 'friends-request' => __( 'A member has sent a friend request to the recipient.', 'buddypress' ), |
| 3384 | | 'friends-request-accepted' => __( 'Recipient has had a friend request accepted by a member.', 'buddypress' ), |
| 3385 | | 'groups-details-updated' => __( "A group's details were updated.", 'buddypress' ), |
| 3386 | | 'groups-invitation' => __( 'A member has sent a group invitation to the recipient.', 'buddypress' ), |
| 3387 | | 'groups-member-promoted' => __( "Recipient's status within a group has changed.", 'buddypress' ), |
| 3388 | | 'groups-membership-request' => __( 'A member has requested permission to join a group.', 'buddypress' ), |
| 3389 | | 'messages-unread' => __( 'Recipient has received a private message.', 'buddypress' ), |
| 3390 | | 'settings-verify-email-change' => __( 'Recipient has changed their email address.', 'buddypress' ), |
| 3391 | | 'groups-membership-request-accepted' => __( 'Recipient had requested to join a group, which was accepted.', 'buddypress' ), |
| 3392 | | 'groups-membership-request-rejected' => __( 'Recipient had requested to join a group, which was rejected.', 'buddypress' ), |
| | 3386 | function bp_email_get_type_schema( $field = 'description' ) { |
| | 3387 | $activity_comment = array( |
| | 3388 | 'description' => __( 'A member has replied to an activity update that the recipient posted.', 'buddypress' ), |
| | 3389 | 'unsubscribe' => array( |
| | 3390 | 'meta_key' => 'notification_activity_new_reply', |
| | 3391 | 'message' => __( 'You will no longer receive emails when someone replies to an update or comment you posted.', 'buddypress' ), |
| | 3392 | ), |
| | 3394 | |
| | 3395 | $activity_comment_author = array( |
| | 3396 | 'description' => __( 'A member has replied to a comment on an activity update that the recipient posted.', 'buddypress' ), |
| | 3397 | 'unsubscribe' => array( |
| | 3398 | 'meta_key' => 'notification_activity_new_reply', |
| | 3399 | 'message' => __( 'You will no longer receive emails when someone replies to an update or comment you posted.', 'buddypress' ), |
| | 3400 | ), |
| | 3401 | ); |
| | 3402 | |
| | 3403 | $activity_at_message = array( |
| | 3404 | 'description' => __( 'Recipient was mentioned in an activity update.', 'buddypress' ), |
| | 3405 | 'unsubscribe' => array( |
| | 3406 | 'meta_key' => 'notification_activity_new_mention', |
| | 3407 | 'message' => __( 'You will no longer receive emails when someone mentions you in an update.', 'buddypress' ), |
| | 3408 | ), |
| | 3409 | ); |
| | 3410 | |
| | 3411 | $groups_at_message = array( |
| | 3412 | 'description' => __( 'Recipient was mentioned in a group activity update.', 'buddypress' ), |
| | 3413 | 'unsubscribe' => array( |
| | 3414 | 'meta_key' => 'notification_activity_new_mention', |
| | 3415 | 'message' => __( 'You will no longer receive emails when someone mentions you in an update.', 'buddypress' ), |
| | 3416 | ), |
| | 3417 | ); |
| | 3418 | |
| | 3419 | $core_user_registration = array( |
| | 3420 | 'description' => __( 'Recipient has registered for an account.', 'buddypress' ), |
| | 3421 | 'unsubscribe' => false, |
| | 3422 | ); |
| | 3423 | |
| | 3424 | $core_user_registration_with_blog = array( |
| | 3425 | 'description' => __( 'Recipient has registered for an account and site.', 'buddypress' ), |
| | 3426 | 'unsubscribe' => false, |
| | 3427 | ); |
| | 3428 | |
| | 3429 | $friends_request = array( |
| | 3430 | 'description' => __( 'A member has sent a friend request to the recipient.', 'buddypress' ), |
| | 3431 | 'unsubscribe' => array( |
| | 3432 | 'meta_key' => 'notification_friends_friendship_request', |
| | 3433 | 'message' => __( 'You will no longer receive emails when someone sends you a friend request.', 'buddypress' ), |
| | 3434 | ), |
| | 3435 | ); |
| | 3436 | |
| | 3437 | $friends_request_accepted = array( |
| | 3438 | 'description' => __( 'Recipient has had a friend request accepted by a member.', 'buddypress' ), |
| | 3439 | 'unsubscribe' => array( |
| | 3440 | 'meta_key' => 'notification_friends_friendship_accepted', |
| | 3441 | 'message' => __( 'You will no longer receive emails when someone accepts your friendship request.', 'buddypress' ), |
| | 3442 | ), |
| | 3443 | ); |
| | 3444 | |
| | 3445 | $groups_details_updated = array( |
| | 3446 | 'description' => __( "A group's details were updated.", 'buddypress' ), |
| | 3447 | 'unsubscribe' => array( |
| | 3448 | 'meta_key' => 'notification_groups_group_updated', |
| | 3449 | 'message' => __( 'You will no longer receive emails when one of your groups is updated.', 'buddypress' ), |
| | 3450 | ), |
| | 3451 | ); |
| | 3452 | |
| | 3453 | $groups_details_updated = array( |
| | 3454 | 'description' => __( "A group's details were updated.", 'buddypress' ), |
| | 3455 | 'unsubscribe' => array( |
| | 3456 | 'meta_key' => 'notification_groups_group_updated', |
| | 3457 | 'message' => __( 'You will no longer receive emails when one of your groups is updated.', 'buddypress' ), |
| | 3458 | ), |
| | 3459 | ); |
| | 3460 | |
| | 3461 | $groups_invitation = array( |
| | 3462 | 'description' => __( 'A member has sent a group invitation to the recipient.', 'buddypress' ), |
| | 3463 | 'unsubscribe' => array( |
| | 3464 | 'meta_key' => 'notification_groups_invite', |
| | 3465 | 'message' => __( 'You will no longer receive emails when you are invited to join a group.', 'buddypress' ), |
| | 3466 | ), |
| | 3467 | ); |
| | 3468 | |
| | 3469 | $groups_member_promoted = array( |
| | 3470 | 'description' => __( "Recipient's status within a group has changed.", 'buddypress' ), |
| | 3471 | 'unsubscribe' => array( |
| | 3472 | 'meta_key' => 'notification_groups_admin_promotion', |
| | 3473 | 'message' => __( 'You will no longer receive emails when you have been promoted in a group.', 'buddypress' ), |
| | 3474 | ), |
| | 3475 | ); |
| | 3476 | |
| | 3477 | $groups_member_promoted = array( |
| | 3478 | 'description' => __( "Recipient's status within a group has changed.", 'buddypress' ), |
| | 3479 | 'unsubscribe' => array( |
| | 3480 | 'meta_key' => 'notification_groups_admin_promotion', |
| | 3481 | 'message' => __( 'You will no longer receive emails when you have been promoted in a group.', 'buddypress' ), |
| | 3482 | ), |
| | 3483 | ); |
| | 3484 | |
| | 3485 | $groups_membership_request = array( |
| | 3486 | 'description' => __( 'A member has requested permission to join a group.', 'buddypress' ), |
| | 3487 | 'unsubscribe' => array( |
| | 3488 | 'meta_key' => 'notification_groups_membership_request', |
| | 3489 | 'message' => __( 'You will no longer receive emails when someone requests to be a member of your group.', 'buddypress' ), |
| | 3490 | ), |
| | 3491 | ); |
| | 3492 | |
| | 3493 | $messages_unread = array( |
| | 3494 | 'description' => __( 'Recipient has received a private message.', 'buddypress' ), |
| | 3495 | 'unsubscribe' => array( |
| | 3496 | 'meta_key' => 'notification_messages_new_message', |
| | 3497 | 'message' => __( 'You will no longer receive emails when someone sends you a message.', 'buddypress' ), |
| | 3498 | ), |
| | 3499 | ); |
| | 3500 | |
| | 3501 | $settings_verify_email_change = array( |
| | 3502 | 'description' => __( 'Recipient has changed their email address.', 'buddypress' ), |
| | 3503 | 'unsubscribe' => false, |
| | 3504 | ); |
| | 3505 | |
| | 3506 | $groups_membership_request_accepted = array( |
| | 3507 | 'description' => __( 'Recipient had requested to join a group, which was accepted.', 'buddypress' ), |
| | 3508 | 'unsubscribe' => array( |
| | 3509 | 'meta_key' => 'notification_membership_request_completed', |
| | 3510 | 'message' => __( 'You will no longer receive emails when your request to join a group has been accepted or denied.', 'buddypress' ), |
| | 3511 | ), |
| | 3512 | ); |
| | 3513 | |
| | 3514 | $groups_membership_request_rejected = array( |
| | 3515 | 'description' => __( 'Recipient had requested to join a group, which was rejected.', 'buddypress' ), |
| | 3516 | 'unsubscribe' => array( |
| | 3517 | 'meta_key' => 'notification_membership_request_completed', |
| | 3518 | 'message' => __( 'You will no longer receive emails when your request to join a group has been accepted or denied.', 'buddypress' ), |
| | 3519 | ), |
| | 3520 | ); |
| | 3521 | |
| | 3522 | $types = array( |
| | 3523 | 'activity-comment' => $activity_comment, |
| | 3524 | 'activity-comment-author' => $activity_comment_author, |
| | 3525 | 'activity-at-message' => $activity_at_message, |
| | 3526 | 'groups-at-message' => $groups_at_message, |
| | 3527 | 'core-user-registration' => $core_user_registration, |
| | 3528 | 'core-user-registration-with-blog' => $core_user_registration_with_blog, |
| | 3529 | 'friends-request' => $friends_request, |
| | 3530 | 'friends-request-accepted' => $friends_request_accepted, |
| | 3531 | 'groups-details-updated' => $groups_details_updated, |
| | 3532 | 'groups-invitation' => $groups_invitation, |
| | 3533 | 'groups-member-promoted' => $groups_member_promoted, |
| | 3534 | 'groups-membership-request' => $groups_membership_request, |
| | 3535 | 'messages-unread' => $messages_unread, |
| | 3536 | 'settings-verify-email-change' => $settings_verify_email_change, |
| | 3537 | 'groups-membership-request-accepted' => $groups_membership_request_accepted, |
| | 3538 | 'groups-membership-request-rejected' => $groups_membership_request_rejected, |
| | 3539 | ); |
| | 3540 | |
| | 3541 | if ( $field !== 'all' ) { |
| | 3542 | return wp_list_pluck( $types, $field ); |
| | 3543 | } else { |
| | 3544 | return $types; |
| | 3545 | } |
| | 3547 | |
| | 3548 | /** |
| | 3549 | * Handles unsubscribing user from notification emails. |
| | 3550 | * |
| | 3551 | * @since 2.6.0 |
| | 3552 | */ |
| | 3553 | function bp_email_unsubscribe_handler() { |
| | 3554 | $emails = bp_email_get_type_schema(); |
| | 3555 | |
| | 3556 | $raw_user_id = ! empty( $_GET['uid'] ) ? absint( $_GET['uid'] ) : 0; |
| | 3557 | $to_check = ! empty( $_GET['nn'] ) ? sanitize_text_field( $_GET['nn'] ) : ''; |
| | 3558 | $unsub_type = ! empty( $_GET['nt'] ) ? sanitize_text_field( $_GET['nt'] ) : ''; |
| | 3559 | |
| | 3560 | $check_args = array( |
| | 3561 | 'uid' => $raw_user_id, |
| | 3562 | 'nt' => $unsub_type, |
| | 3563 | ); |
| | 3564 | |
| | 3565 | $check = bp_hash_array( $check_args ); |
| | 3566 | |
| | 3567 | // Check required values. |
| | 3568 | if ( ! $raw_user_id || ! $unsub_type || ! $to_check || ! array_key_exists( $unsub_type, $emails ) ) { |
| | 3569 | $redirect_to = site_url( 'wp-login.php' ); |
| | 3570 | $result_msg = __( 'Something has gone wrong.', 'buddypress' ); |
| | 3571 | $unsub_msg = __( 'Please log in and go to your settings to unsubscribe from notification emails.', 'buddypress' ); |
| | 3572 | |
| | 3573 | // Check valid hash. |
| | 3574 | } elseif ( ! hash_equals( $check, $to_check ) ) { |
| | 3575 | $redirect_to = site_url( 'wp-login.php' ); |
| | 3576 | $result_msg = __( 'Something has gone wrong.', 'buddypress' ); |
| | 3577 | $unsub_msg = __( 'Please log in and go to your settings to unsubscribe from notification emails.', 'buddypress' ); |
| | 3578 | |
| | 3579 | // Don't let authenticated users unsubscribe other users' email notifications. |
| | 3580 | } elseif ( is_user_logged_in() && get_current_user_id() !== $raw_user_id ) { |
| | 3581 | $redirect_to = sprintf( |
| | 3582 | '%s%s/notifications/', |
| | 3583 | bp_core_get_user_domain( get_current_user_id() ), |
| | 3584 | function_exists( 'bp_get_settings_slug' ) ? bp_get_settings_slug() : 'settings' |
| | 3585 | ); |
| | 3586 | |
| | 3587 | $result_msg = __( 'Something has gone wrong.', 'buddypress' ); |
| | 3588 | $unsub_msg = __( 'Please go to your settings to unsubscribe from notification emails.', 'buddypress' ); |
| | 3589 | |
| | 3590 | } else { |
| | 3591 | $redirect_to = sprintf( |
| | 3592 | '%s%s/notifications/', |
| | 3593 | bp_core_get_user_domain( $raw_user_id ), |
| | 3594 | function_exists( 'bp_get_settings_slug' ) ? bp_get_settings_slug() : 'settings' |
| | 3595 | ); |
| | 3596 | |
| | 3597 | // Unsubscribe. |
| | 3598 | // djpaultodo - raw_user_id not safe. verify hash match will validate the user id. |
| | 3599 | $meta_key = $emails[ $unsub_type ]['unsubscribe']['meta_key']; |
| | 3600 | $is_unsubscribed = bp_update_user_meta( $raw_user_id, $meta_key, 'no' ); |
| | 3601 | |
| | 3602 | $result_msg = $emails[ $unsub_type ]['unsubscribe']['message']; |
| | 3603 | $unsub_msg = __( 'You can change this or any other email notification preferences in your email settings.', 'buddypress' ); |
| | 3604 | } |
| | 3605 | |
| | 3606 | $message = sprintf( |
| | 3607 | '%1$s <a href="%2$s">%3$s</a>', |
| | 3608 | $result_msg, |
| | 3609 | esc_url( $redirect_to ), |
| | 3610 | $unsub_msg |
| | 3611 | ); |
| | 3612 | |
| | 3613 | bp_core_add_message( $message ); |
| | 3614 | bp_core_redirect( bp_core_get_user_domain( $raw_user_id ) ); |
| | 3615 | exit; |
| | 3616 | } |
| | 3617 | |
| | 3618 | /** |
| | 3619 | * Creates unsubscribe link for notification emails. |
| | 3620 | * |
| | 3621 | * @since |
| | 3622 | * |
| | 3623 | * @param string $redirect_to The URL to which the unsubscribe query string is appended. |
| | 3624 | * @param array $args { |
| | 3625 | * |
| | 3626 | * Used to build unsubscribe query string. |
| | 3627 | * |
| | 3628 | * @type string $notification_type Which notification type is being sent. |
| | 3629 | * @type string $user_id The ID of the user to whom the notification is sent. |
| | 3630 | * @type string $redirect_to Optional. The url to which the user will be redirected. Default is the activity directory. |
| | 3631 | * |
| | 3632 | * } |
| | 3633 | * @return string The unsubscribe link. |
| | 3634 | */ |
| | 3635 | function bp_email_get_unsubscribe_link( $args = null ) { |
| | 3636 | // djpaultodo - review/tweak function. |
| | 3637 | $bp_emails_type_schema = bp_email_get_type_schema(); |
| | 3638 | |
| | 3639 | if ( ! is_array( $args ) || ! isset( $args['notification_type'] ) || ! array_key_exists( $args['notification_type'], $bp_emails_type_schema ) ) { |
| | 3640 | return site_url( 'wp-login.php' ); |
| | 3641 | } |
| | 3642 | |
| | 3643 | $notification_type = $unsubscribe_args['nt'] = esc_attr( $args['notification_type'] ); |
| | 3644 | $user_id = $unsubscribe_args['uid'] = (int) $args['user_id']; |
| | 3645 | |
| | 3646 | // If the activity type is not unsubscribable (ununsubscribable), return false. |
| | 3647 | if ( empty( $bp_emails_type_schema[ $notification_type ]['unsubscribe'] ) ) { |
| | 3648 | return false; |
| | 3649 | } |
| | 3650 | |
| | 3651 | $redirect_to = ( isset( $args['redirect_to'] ) ) ? isset( $args['redirect_to'] ) : bp_get_activity_directory_permalink(); |
| | 3652 | |
| | 3653 | $check = bp_hash_array( $unsubscribe_args ); |
| | 3654 | |
| | 3655 | $unsubscribe_args['nn'] = $check; |
| | 3656 | $unsubscribe_args['action'] = 'unsubscribe'; |
| | 3657 | |
| | 3658 | $unsubscribe_link = esc_url_raw( add_query_arg( $unsubscribe_args, $redirect_to ) ); |
| | 3659 | |
| | 3660 | /** |
| | 3661 | * Filters the unsubscribe link. |
| | 3662 | * |
| | 3663 | * @since |
| | 3664 | * |
| | 3665 | * @param string $redirect_to URL to which the unsubscribe query string is appended. |
| | 3666 | * @param array $args Used to build unsubscribe query string. |
| | 3667 | */ |
| | 3668 | return apply_filters( 'bp_email_get_unsubscribe_link', $unsubscribe_link, $redirect_to, $args ); |
| | 3669 | } |
| | 3670 | |
| | 3671 | /** |
| | 3672 | * Get a persistent salt for email unsubscribe links, not dependent on salts in wp-config.php. |
| | 3673 | * |
| | 3674 | * @since 2.6.0 |
| | 3675 | * |
| | 3676 | * @return string |
| | 3677 | */ |
| | 3678 | function bp_email_get_salt() { |
| | 3679 | $salt = bp_get_option( 'bp-emails-unsubscribe-salt', null ); |
| | 3680 | |
| | 3681 | if ( is_null( $salt ) ) { |
| | 3682 | $salt = base64_encode( wp_generate_password( 12, true, true ) ); |
| | 3683 | bp_add_option( 'bp-emails-unsubscribe-salt', $salt ); |
| | 3684 | } |
| | 3685 | |
| | 3686 | return $salt; |
| | 3687 | } |
| | 3688 | |
| | 3689 | /** |
| | 3690 | * Get a function that makes a checkable hash for the given args. |
| | 3691 | * |
| | 3692 | * @param array $args Any array. |
| | 3693 | * |
| | 3694 | * @return string |
| | 3695 | * |
| | 3696 | */ |
| | 3697 | function bp_hash_array( $args ) { |
| | 3698 | $salt = bp_email_get_salt(); |
| | 3699 | |
| | 3700 | // the key order shouldn't matter when checking two arrays, so the array is sorted |
| | 3701 | ksort( $args ); |
| | 3702 | |
| | 3703 | $string = ( is_array( $args ) ) ? implode( ':', $args ) : (string) $args; |
| | 3704 | |
| | 3705 | // should this return a substring like the nonce does? It's quite long. |
| | 3706 | $check = hash_hmac( 'sha1', $string, $salt ); |
| | 3707 | |
| | 3708 | return $check; |
| | 3709 | } |