PHP voor formulier (<template_directory>/login-form.php)
<?php
defined('WPINC') || die();
?>
<div class="wbmz-container">
<p class="form-row">
<label for="wbmz-username" class="form-label"><?php esc_html_e('Gebruikersnaam of email adres', 'wbmz');?></label>
<input id="wbmz-username" class="form-control" name="username" type="text" placeholder="<?php esc_html_e('Gebruikersnaam of email adres', 'wbmz');?>" />
</p>
<p class="form-row">
<label for="wbmz-password" class="form-label"><?php esc_html_e('Wachtwoord', 'wbmz');?></label>
<input id="wbmz-password" class="form-control"name="password" type="password" placeholder="<?php esc_html_e('Wachtwoord', 'wbmz');?>" />
</p>
<p class="form-row">
<button class="wbmz-login button btn btn-primary"><?php esc_html_e('Inloggen', 'wbmz');?></button>
</p>
</div>
PHP voor de acties (<template_directory>/inc/ajax-login.php) (indien nodig ook in functions.php aanpassen)
<?php
defined('WPINC') || die();
// Consider changing these.
const WBMZ_MENU_LOCATION = 'primaryy';
const WBMZ_LOGIN_RETRY_PAUSE = 5; // secs
const WBMZ_SPINNER_FILE_NAME = 'spinner.svg';
// You probably don't need to change these.
const WBMZ_LOGIN_ACTION = 'wbmz-login';
const WBMZ_LOGIN_FORM_FILE_NAME = 'login-form.php';
/**
* Listen for incoming login requests from the Ajax form.
*/
function wbmz_init() {
add_action('wp_ajax_nopriv_' . WBMZ_LOGIN_ACTION, 'wbmz_try_to_login');
}
add_action('init', 'wbmz_init');
/**
* Get the IP address of the current browser.
* */
function wbmz_client_ip() {
global $wbmz_client_ip;
if (!is_null($wbmz_client_ip)) {
// We've already discovered the browser's IP address.
} elseif (!empty($_SERVER['HTTP_CLIENT_IP'])) {
$wbmz_client_ip = filter_var($_SERVER['HTTP_CLIENT_IP'], FILTER_VALIDATE_IP);
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$wbmz_client_ip = filter_var($_SERVER['HTTP_X_FORWARDED_FOR'], FILTER_VALIDATE_IP);
} else {
$wbmz_client_ip = filter_var($_SERVER['REMOTE_ADDR'], FILTER_VALIDATE_IP);
}
return $wbmz_client_ip;
}
/**
* A convenience function that lets us disable the login menu item under
* certain conditions.
*/
function wbmz_is_login_menu_required() {
$is_required = !is_user_logged_in();
// You can put extra conditions in here.
// if ($some_test == true) {
// $is_required = false;
// }
return $is_required;
}
function wbmz_front_door_url() {
$login_page_url = wp_login_url(home_url($_SERVER['REQUEST_URI']));
// If WooCommerce is installed, use the my-account page as the frontdoor,
if (function_exists('wc_get_account_endpoint_url')) {
$frontdoor_url = wc_get_account_endpoint_url('dashboard');
}
return $frontdoor_url;
}
/**
* We add our assets to every page of the site, because the primay
* nav menu is probably on every page.
*/
function wbmz_enqueue_scripts() {
$base_uri = get_stylesheet_directory_uri();
$version = wp_get_theme()->get('Version');
// Our login form stylesheet.
/*wp_enqueue_style(
'wbmz',
$base_uri . '/wpt-ajax-login/wpt-ajax-login.css',
null, // We don't have any style dependencies.
$version
);*/
// Enqueue our main JavaScript file.
wp_enqueue_script(
'wbmz',
$base_uri . '/assets/js/ajax-login.js',
array('jquery'), // Our code depends on jquery.
$version
);
// Pass some settings and variables to the browser in a
// JavaScript global variable called wbmzData.
wp_localize_script(
'wbmz',
'wbmzData',
array(
'ajaxUrl' => admin_url('admin-ajax.php'),
'action' => WBMZ_LOGIN_ACTION,
'frontDoor' => wbmz_front_door_url(),
'spinnerUrl' => $base_uri . '/assets/img/' . WBMZ_SPINNER_FILE_NAME,
)
);
}
add_action('wp_enqueue_scripts', 'wbmz_enqueue_scripts');
/**
* Render the login menu item and form. $items is a string that we're going
* to append our HTML to.
*/
function wbmz_wp_nav_menu_items($items, $args) {
// The file name of the login form (PHP) we're going to "include".
$file_name = dirname(__FILE__) . '/' . WBMZ_LOGIN_FORM_FILE_NAME;
if (!wbmz_is_login_menu_required()) {
// We're already logged in so we don't need a login form.
} elseif ($args->theme_location != WBMZ_MENU_LOCATION) {
// These aren't the menu item's you're looking for.
} elseif (!is_file($file_name)) {
$items .= sprintf(
'<li class="menu-item"><a class="menu-link"><strong>%s</strong></a></li>',
WBMZ_LOGIN_FORM_FILE_NAME
);
} else {
// Start rendering the HTML for the menu item.
$outer_classes = array(
'menu-item',
'menu-item-has-children',
'menu-item-login',
);
$items .= sprintf('<li class="%s">', esc_attr(implode(' ', $outer_classes)));
// The login menu item. You can change the "Login" label here.
$items .= sprintf(
'<a href="%s">%s</a>',
esc_url(wbmz_front_door_url()),
esc_html__('Inloggen', 'wbmz')
);
// Start rendering a sub menu to hold the login form.
$sub_menu_classes = array(
'sub-menu',
'wbmz-container',
);
$items .= sprintf('<ul class="%s">', esc_attr(implode(' ', $sub_menu_classes)));
// Include the login form PHP/HTML file.
ob_start();
include $file_name;
$items .= ob_get_clean();
$items .= '</ul>'; // .sub-menu
$items .= '</li>'; // .menu-item
}
return $items;
}
add_filter('wp_nav_menu_items', 'wbmz_wp_nav_menu_items', 10, 2);
/**
* The main function will try to log in to the site by sanitising and
* authenticating $_POST['username'] and $_POST['password']
*/
function wbmz_try_to_login() {
// If we can't determine the client's IP address then something is very
// wrong - possibly a hack attempt. Don't do anything.
if (empty($client_ip_address = wbmz_client_ip())) {
die();
}
$client_key = 'login_attempt_' . $client_ip_address;
$status_code = 200;
$response = array(
'isLoggedIn' => false,
'errorMessage' => '',
);
if ((get_transient($client_key) !== false)) {
$response['errorMessage'] = 'Probeer niet teveel achter elkaar in te loggen.';
} elseif (empty($username = sanitize_text_field($_POST['username']))) {
$response['errorMessage'] = 'Geen gebruikersnaam ingevuld';
} elseif (empty($password = sanitize_text_field($_POST['password']))) {
$response['errorMessage'] = 'Geen wachtwoord ingevuld';
} elseif (!is_a($user = wp_authenticate($username, $password), 'WP_User')) {
$response['errorMessage'] = 'Onjuiste gebruikersnaam en/of wachtwoord ingevuld.';
} else {
// Logged in OK.
$response['isLoggedIn'] = true;
// We need to do this so wp_send_json() can return the cookie in
// our response.
wp_set_auth_cookie(
$user->ID,
true// << This is the "remember me" option.
);
}
if (!empty($response['errorMessage'])) {
error_log($response['errorMessage']);
set_transient($client_key, '1', WBMZ_LOGIN_RETRY_PAUSE);
}
wp_send_json(
$response,
$status_code
);
}
jQuery (<template_directory>/assets/js/ajax-login.js)
(function($) {
'use strict';
$(window).on('load', function() {
console.log('WBMZ Ajax Login : load');
/**
* If wbmzData hasn't been set using wp_localize_script() then don't do anything.
*/
if (typeof wbmzData != 'undefined') {
/**
* Create and attach an IMG to each login form button (there should
* only be one).
*/
$('.wbmz-login.button').each(function(index, el) {
var spinner = $(`<img src="${wbmzData.spinnerUrl}" class="login-spinner" />`);
$(this).append(spinner);
});
/**
* Listen for the "click" event on each login button.
*/
$('.wbmz-login.button').click(function(event) {
event.preventDefault();
var container = $(this).closest('.wbmz-container');
tryToLogin(container);
});
/**
* For every input text|password element in our login form, listen
* for the Enter key (ASCII code 13).
*/
$('.wbmz-container input[type="text"], .wbmz-container input[type="password"]').keypress(function(event) {
if (event.which == 13) {
event.preventDefault();
var container = $(this).closest('.wbmz-container');
tryToLogin(container);
};
});
function tryToLogin(container) {
// This is our request object. Each of these keys (action,
// username & password) can be picked up in the PHP $_POST object.
var request = {
'action': wbmzData.action,
'username': $(container).find('#wbmz-username').val(),
'password': $(container).find('#wbmz-password').val()
};
if (!request.username || !request.password) {
// Missing user name or password.
// console.log('Missing user name and/or password.');
} else if ($(container).hasClass('working')) {
// We've been asked to login, even though the login box
// already has the "working" class attached to it.
// This should never happen.
// console.log('Already trying to log in. Please wait.');
} else {
// console.log('Attempting to log in now.');
$(container).addClass('working');
$(container).find('input, button').prop('disabled', true);
// Send our login request object to /wp-admin/admin-ajax.php
$.post(wbmzData.ajaxUrl, request)
.fail(function() {
// There was an internal server error of some sort,
// so direct the user to the main WP Login page.
if (wbmzData.frontDoor) {
window.location.href = wbmzData.frontDoor;
}
})
.done(function(response) {
if (response.errorMessage) {
alert(response.errorMessage);
} else if (!response.isLoggedIn) {
// Unknown error logging in.
} else {
// We've successfully logged-in.
// Reload the current page.
location.reload();
}
})
.always(function(response) {
if (!response.isLoggedIn) {
$(container).find('input, button').prop('disabled', false);
$(container).removeClass('working');
}
});
}
}
}
});
})(jQuery);
CSS
.sub-menu.wbmz-container {
padding: 1em;
box-shadow: 0 0 3em #00000022;
min-width: 15em;
position: absolute;
}
.wbmz-container input,
.wbmz-container button {
position: relative;
transition: 0.3s;
}
.wbmz-container .form-row:not( :last-of-type) {
margin-bottom: 1em;
}
.wbmz-container .form-row:last-of-type {
margin-bottom: 0;
}
.wbmz-container button:disabled,
.wbmz-container input:disabled {
opacity: 0.75;
}
.wbmz-container .login-spinner {
display: none;
width: 1.5em;
position: absolute;
right: 0.5em;
top: 50%;
transform: translateY(-50%);
}
.wbmz-container.working .login-spinner {
display: block;
}
Voor de SVG spinners klik HIER
#AJAX #functions #inloggen #jQuery #js #login #php