Skip to content

Instantly share code, notes, and snippets.

@mustafauysal
Created December 5, 2025 13:08
Show Gist options
  • Select an option

  • Save mustafauysal/4f077ba7b674ece53148f5b88282ad8c to your computer and use it in GitHub Desktop.

Select an option

Save mustafauysal/4f077ba7b674ece53148f5b88282ad8c to your computer and use it in GitHub Desktop.
<?php
/**
* Magic Login Pro - Email Confirmation Enforcement
*
* This snippet requires users to confirm their email address when registering
* via Magic Login Pro. Users must click the magic login link in their email
* to confirm their email address before they can log in.
*
* How it works:
* 1. When a user registers, they are marked as "email unconfirmed"
* 2. A confirmation email is sent with a magic login link
* 3. When the user clicks the link and logs in, their email is confirmed
* 4. Users with unconfirmed emails cannot log in via regular means
*
* @package MagicLoginEmailConfirmation
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* User meta key for email confirmation status
*/
define( 'MAGIC_LOGIN_EMAIL_CONFIRMED_META', '_custom_magic_login_email_confirmed_flag' );
/**
* Mark newly registered users as unconfirmed
*
* @param int $user_id User ID.
* @param array $userdata User data.
*/
add_action( 'magic_login_registration_after_user_create', function ( $user_id, $userdata ) {
update_user_meta( $user_id, MAGIC_LOGIN_EMAIL_CONFIRMED_META, 'no' );
}, 5, 2 );
/**
* Confirm email when user successfully logs in via magic link
*
* @param WP_User $user User object.
* @param array $current_token Token data.
*/
add_action( 'magic_login_logged_in', function ( $user, $current_token ) {
$is_confirmed = get_user_meta( $user->ID, MAGIC_LOGIN_EMAIL_CONFIRMED_META, true );
if ( 'no' === $is_confirmed ) {
update_user_meta( $user->ID, MAGIC_LOGIN_EMAIL_CONFIRMED_META, 'yes' );
/**
* Fires when a user's email is confirmed via magic login
*
* @param WP_User $user User object.
*/
do_action( 'magic_login_email_confirmed', $user );
}
}, 10, 2 );
/**
* Block login for users with unconfirmed emails (non-magic-login attempts)
*
* @param WP_User|WP_Error $user User object or error.
* @param string $password Password.
*
* @return WP_User|WP_Error
*/
add_filter( 'wp_authenticate_user', function ( $user, $password ) {
if ( is_wp_error( $user ) ) {
return $user;
}
$is_confirmed = get_user_meta( $user->ID, MAGIC_LOGIN_EMAIL_CONFIRMED_META, true );
// If meta doesn't exist (user registered before this snippet), allow login
if ( '' === $is_confirmed ) {
return $user;
}
if ( 'no' === $is_confirmed ) {
return new WP_Error(
'email_not_confirmed',
sprintf(
/* translators: %s: resend link */
__( '<strong>Error:</strong> Please confirm your email address before logging in. Check your inbox for the confirmation email. <a href="%s">Resend confirmation email</a>', 'magic-login' ),
esc_url( add_query_arg( [
'action' => 'magic_login_resend_confirmation',
'user_login' => rawurlencode( $user->user_email ),
'_wpnonce' => wp_create_nonce( 'resend_confirmation_' . $user->ID ),
], wp_login_url() ) )
)
);
}
return $user;
}, 30, 2 );
/**
* Handle resend confirmation email request
*/
add_action( 'login_init', function () {
if ( ! isset( $_GET['action'] ) || 'magic_login_resend_confirmation' !== $_GET['action'] ) {
return;
}
if ( ! isset( $_GET['user_login'] ) || ! isset( $_GET['_wpnonce'] ) ) {
return;
}
$user_login = sanitize_email( wp_unslash( $_GET['user_login'] ) );
$user = get_user_by( 'email', $user_login );
if ( ! $user ) {
wp_safe_redirect( add_query_arg( 'magic_confirmation', 'sent', wp_login_url() ) );
exit;
}
// Verify nonce
if ( ! wp_verify_nonce( $_GET['_wpnonce'], 'resend_confirmation_' . $user->ID ) ) {
wp_safe_redirect( add_query_arg( 'magic_confirmation', 'sent', wp_login_url() ) );
exit;
}
$is_confirmed = get_user_meta( $user->ID, MAGIC_LOGIN_EMAIL_CONFIRMED_META, true );
// Only resend if not already confirmed
if ( 'no' === $is_confirmed ) {
magic_login_send_confirmation_email( $user );
}
wp_safe_redirect( add_query_arg( 'magic_confirmation', 'sent', wp_login_url() ) );
exit;
} );
/**
* Display confirmation sent message on login page
*/
add_filter( 'login_message', function ( $message ) {
if ( isset( $_GET['magic_confirmation'] ) && 'sent' === $_GET['magic_confirmation'] ) {
$message .= '<p class="message">' . esc_html__( 'A confirmation email has been sent to your email address. Please check your inbox and click the link to confirm your email.', 'magic-login' ) . '</p>';
}
return $message;
} );
/**
* Send confirmation email with magic login link
*
* @param WP_User $user User object.
*/
function magic_login_send_confirmation_email( $user ) {
if ( ! function_exists( 'MagicLogin\Utils\create_login_link' ) ) {
return;
}
$login_link = \MagicLogin\Utils\create_login_link( $user, 'email' );
$subject = sprintf(
/* translators: %s: site name */
__( '[%s] Please confirm your email address', 'magic-login' ),
get_bloginfo( 'name' )
);
$message = sprintf(
/* translators: 1: user display name, 2: site name, 3: login link, 4: site name */
__(
'Hello %1$s,
Please confirm your email address to complete your registration on %2$s.
Click the link below to confirm your email and log in:
%3$s
If you did not register on %4$s, please ignore this email.
Thanks,
%4$s',
'magic-login'
),
$user->display_name,
get_bloginfo( 'name' ),
$login_link,
get_bloginfo( 'name' )
);
/**
* Filter the confirmation email subject
*
* @param string $subject Email subject.
* @param WP_User $user User object.
*/
$subject = apply_filters( 'magic_login_confirmation_email_subject', $subject, $user );
/**
* Filter the confirmation email message
*
* @param string $message Email message.
* @param WP_User $user User object.
* @param string $login_link Magic login link.
*/
$message = apply_filters( 'magic_login_confirmation_email_message', $message, $user, $login_link );
wp_mail( $user->user_email, $subject, $message );
}
/**
* Add email confirmation status column to users list
*
* @param array $columns User list columns.
*
* @return array
*/
add_filter( 'manage_users_columns', function ( $columns ) {
$columns['email_confirmed'] = __( 'Email Confirmed', 'magic-login' );
return $columns;
} );
/**
* Display email confirmation status in users list
*
* @param string $value Column value.
* @param string $column_name Column name.
* @param int $user_id User ID.
*
* @return string
*/
add_filter( 'manage_users_custom_column', function ( $value, $column_name, $user_id ) {
if ( 'email_confirmed' !== $column_name ) {
return $value;
}
$is_confirmed = get_user_meta( $user_id, MAGIC_LOGIN_EMAIL_CONFIRMED_META, true );
if ( '' === $is_confirmed ) {
return '<span style="color: #999;">—</span>';
}
if ( 'yes' === $is_confirmed ) {
return '<span style="color: #46b450;">&#10003; ' . esc_html__( 'Confirmed', 'magic-login' ) . '</span>';
}
return '<span style="color: #dc3232;">&#10007; ' . esc_html__( 'Pending', 'magic-login' ) . '</span>';
}, 10, 3 );
/**
* Add bulk action to manually confirm user emails
*
* @param array $actions Bulk actions.
*
* @return array
*/
add_filter( 'bulk_actions-users', function ( $actions ) {
$actions['confirm_email'] = __( 'Confirm Email', 'magic-login' );
return $actions;
} );
/**
* Handle bulk confirm email action
*
* @param string $redirect_url Redirect URL.
* @param string $action Action name.
* @param array $user_ids User IDs.
*
* @return string
*/
add_filter( 'handle_bulk_actions-users', function ( $redirect_url, $action, $user_ids ) {
if ( 'confirm_email' !== $action ) {
return $redirect_url;
}
foreach ( $user_ids as $user_id ) {
update_user_meta( $user_id, MAGIC_LOGIN_EMAIL_CONFIRMED_META, 'yes' );
}
return add_query_arg( 'emails_confirmed', count( $user_ids ), $redirect_url );
}, 10, 3 );
/**
* Display admin notice after bulk confirm
*/
add_action( 'admin_notices', function () {
if ( ! isset( $_GET['emails_confirmed'] ) ) {
return;
}
$count = intval( $_GET['emails_confirmed'] );
printf(
'<div class="notice notice-success is-dismissible"><p>' .
/* translators: %d: number of users confirmed */
esc_html( _n( '%d user email confirmed.', '%d user emails confirmed.', $count, 'magic-login' ) ) .
'</p></div>',
$count
);
} );
/**
* Add user profile field for email confirmation status
*
* @param WP_User $user User object.
*/
add_action( 'show_user_profile', 'magic_login_email_confirmation_profile_field' );
add_action( 'edit_user_profile', 'magic_login_email_confirmation_profile_field' );
function magic_login_email_confirmation_profile_field( $user ) {
if ( ! current_user_can( 'edit_users' ) ) {
return;
}
$is_confirmed = get_user_meta( $user->ID, MAGIC_LOGIN_EMAIL_CONFIRMED_META, true );
// Don't show if user never had confirmation requirement
if ( '' === $is_confirmed ) {
return;
}
?>
<h3><?php esc_html_e( 'Email Confirmation', 'magic-login' ); ?></h3>
<table class="form-table">
<tr>
<th><label for="email_confirmed"><?php esc_html_e( 'Email Status', 'magic-login' ); ?></label></th>
<td>
<select name="email_confirmed" id="email_confirmed">
<option value="yes" <?php selected( $is_confirmed, 'yes' ); ?>><?php esc_html_e( 'Confirmed', 'magic-login' ); ?></option>
<option value="no" <?php selected( $is_confirmed, 'no' ); ?>><?php esc_html_e( 'Pending Confirmation', 'magic-login' ); ?></option>
</select>
<p class="description"><?php esc_html_e( 'Set whether this user\'s email address is confirmed.', 'magic-login' ); ?></p>
</td>
</tr>
</table>
<?php
}
/**
* Save email confirmation status from user profile
*
* @param int $user_id User ID.
*/
add_action( 'personal_options_update', 'magic_login_save_email_confirmation_profile_field' );
add_action( 'edit_user_profile_update', 'magic_login_save_email_confirmation_profile_field' );
function magic_login_save_email_confirmation_profile_field( $user_id ) {
if ( ! current_user_can( 'edit_users' ) ) {
return;
}
if ( isset( $_POST['email_confirmed'] ) ) {
$status = sanitize_text_field( $_POST['email_confirmed'] );
if ( in_array( $status, [ 'yes', 'no' ], true ) ) {
update_user_meta( $user_id, MAGIC_LOGIN_EMAIL_CONFIRMED_META, $status );
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment