Skip to content

Instantly share code, notes, and snippets.

@andrewlimaza
Last active June 11, 2026 12:45
Show Gist options
  • Select an option

  • Save andrewlimaza/76741b456d936426743239ab6d47bb66 to your computer and use it in GitHub Desktop.

Select an option

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.
<?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