Last active
June 11, 2026 12:45
-
-
Save andrewlimaza/76741b456d936426743239ab6d47bb66 to your computer and use it in GitHub Desktop.
PMPro Approvals, add an approve/deny link to one click action the pending member from email.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * Creates {{approve_action_link}} and {{deny_action_link}} for pending emails. | |
| * Only add it to the pending approval (admin) email template. | |
| * Add this code to your site by following this guide - https://www.paidmembershipspro.com/create-a-plugin-for-pmpro-customizations/ | |
| */ | |
| /** | |
| * Build the frontend URL for an email-based approval or denial action. | |
| * | |
| * @param int $user_id The member's user ID. | |
| * @param int $level_id The membership level ID. | |
| * @param string $action 'approve' or 'deny'. | |
| * @return string The full URL. | |
| */ | |
| function my_pmpro_get_approval_action_url( $user_id, $level_id, $action ) { | |
| return add_query_arg( array( | |
| 'pmpro_email_approval' => $action, | |
| 'pmpro_member' => $user_id, | |
| 'pmpro_level' => $level_id, | |
| ), home_url( '/' ) ); | |
| } | |
| /** | |
| * Inject !!approve_action_link!! and !!deny_action_link!! variables into the | |
| * admin pending notification email. This filter runs for both the legacy email | |
| * class and the newer PMPro_Email_Template system. | |
| */ | |
| function my_pmpro_approvals_add_action_links( $data, $member, $admin ) { | |
| if ( empty( $member ) || ! isset( $data['membership_id'] ) ) { | |
| return $data; | |
| } | |
| $level_id = intval( $data['membership_id'] ); | |
| if ( $level_id < 1 ) { | |
| return $data; | |
| } | |
| if ( ! class_exists( 'PMPro_Approvals' ) || ! PMPro_Approvals::requiresApproval( $level_id ) ) { | |
| $data['approve_action_link'] = ''; | |
| $data['deny_action_link'] = ''; | |
| return $data; | |
| } | |
| $data['approve_action_link'] = my_pmpro_get_approval_action_url( $member->ID, $level_id, 'approve' ); | |
| $data['deny_action_link'] = my_pmpro_get_approval_action_url( $member->ID, $level_id, 'deny' ); | |
| return $data; | |
| } | |
| add_filter( 'pmpro_approvals_admin_pending_email_data', 'my_pmpro_approvals_add_action_links', 10, 3 ); | |
| /** | |
| * Process an email-based approval/denial on page load. Requires the user to | |
| * be logged in with the pmpro_approvals capability; redirects to login otherwise. | |
| */ | |
| function my_pmpro_process_email_approval_action() { | |
| if ( empty( $_GET['pmpro_email_approval'] ) ) { | |
| return; | |
| } | |
| $action = sanitize_key( $_GET['pmpro_email_approval'] ); | |
| $user_id = isset( $_GET['pmpro_member'] ) ? intval( $_GET['pmpro_member'] ) : 0; | |
| $level_id = isset( $_GET['pmpro_level'] ) ? intval( $_GET['pmpro_level'] ) : 0; | |
| if ( ! in_array( $action, array( 'approve', 'deny' ), true ) || ! $user_id || ! $level_id ) { | |
| wp_die( 'Invalid approval request.', 'Error', array( 'response' => 400 ) ); | |
| } | |
| if ( ! is_user_logged_in() ) { | |
| wp_safe_redirect( wp_login_url( add_query_arg( $_GET, home_url( '/' ) ) ) ); | |
| exit; | |
| } | |
| $capability = current_user_can( 'pmpro_approvals' ) ? 'pmpro_approvals' : 'manage_options'; | |
| if ( ! current_user_can( $capability ) ) { | |
| wp_die( 'You do not have permission to perform this action.', 'Error', array( 'response' => 403 ) ); | |
| } | |
| if ( ! class_exists( 'PMPro_Approvals' ) ) { | |
| wp_die( 'PMPro Approvals plugin is not active.', 'Error', array( 'response' => 500 ) ); | |
| } | |
| $member = get_user_by( 'ID', $user_id ); | |
| $name = $member ? $member->display_name : "User #{$user_id}"; | |
| if ( 'approve' === $action ) { | |
| PMPro_Approvals::approveMember( $user_id, $level_id ); | |
| $notice = 'approved'; | |
| } else { | |
| PMPro_Approvals::denyMember( $user_id, $level_id ); | |
| $notice = 'denied'; | |
| } | |
| wp_safe_redirect( add_query_arg( array( | |
| 'page' => 'pmpro-approvals', | |
| 'pmpro_approval_notice' => $notice, | |
| 'pmpro_approval_name' => rawurlencode( $name ), | |
| ), admin_url( 'admin.php' ) ) ); | |
| exit; | |
| } | |
| add_action( 'init', 'my_pmpro_process_email_approval_action' ); | |
| /** | |
| * Display an admin notice on the approvals page after an email-based action. | |
| * Function name must start with "pmpro" to survive PMPro's notice filter. | |
| */ | |
| function pmpro_approval_email_action_notice() { | |
| if ( empty( $_GET['page'] ) || $_GET['page'] !== 'pmpro-approvals' ) { | |
| return; | |
| } | |
| if ( empty( $_GET['pmpro_approval_notice'] ) ) { | |
| return; | |
| } | |
| $notice = sanitize_key( $_GET['pmpro_approval_notice'] ); | |
| $name = isset( $_GET['pmpro_approval_name'] ) ? esc_html( rawurldecode( $_GET['pmpro_approval_name'] ) ) : 'Member'; | |
| if ( 'approved' === $notice ) { | |
| $type = 'success'; | |
| $text = "<strong>{$name}</strong> has been approved."; | |
| } elseif ( 'denied' === $notice ) { | |
| $type = 'warning'; | |
| $text = "<strong>{$name}</strong> has been denied."; | |
| } else { | |
| return; | |
| } | |
| echo "<div class='notice notice-{$type} is-dismissible'><p>{$text}</p></div>"; | |
| } | |
| add_action( 'admin_notices', 'pmpro_approval_email_action_notice' ); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment