The Wordpress Ultimate Member (UM) plugin allows us to set newly registered users to ‘Pending’ through wp-admin.
The Pending function does 2 things:
Sets the user status to ‘awaiting admin approval’
Sends the user an email
See here:
function pending(){
global $ultimatemember;
$this->set_status('awaiting_admin_review');
$ultimatemember->mail->send( um_user('user_email'), 'pending_email' );
But, there is no way to set existing users to ‘Pending’ admin approval if users edit an existing account.
I’m not strong at PHP, but I figured out a hook into the ‘um_user_edit_profile’ action, so that if existing users edit their profile the status is changed to ‘pending’.
See here:
// Set profile to under pending after edits
add_action('um_user_edit_profile', 'um_post_edit_pending_hook', 10, 2);
function um_post_edit_pending_hook($user_id, $args){
if ( is_super_admin() ) {
return false;
} else {
global $ultimatemember;
$ultimatemember->user->pending();
}
}
Unfortunately, I have just discovered that the ‘um_user_edit_profile’ action is also used at registration, so my hook triggers at registration too which results in two emails being sent.
I’ve tried to overcome this by:
Adding and if statement so the action is only triggered for logged in users:
// Set profile to under review after edits
add_action('um_user_edit_profile', 'um_post_edit_pending_hook', 10, 2);
function um_post_edit_pending_hook($user_id, $args){
if ( is_super_admin() ) {
return false;
} else {
if ( is_user_logged_in() ) {
global $ultimatemember;
$ultimatemember->user->pending();
}
}
By trying to set the status to ‘awaiting admin approval’ without including the email:
// Set profile to under review after edits
add_action('um_user_edit_profile', 'um_post_edit_pending_hook', 10, 2);
function um_post_edit_pending_hook($user_id, $args){
if ( is_super_admin() ) {
return false;
} else {
global $ultimatemember;
$ultimatemember->set_status('awaiting_admin_review');
}
}
// Set profile to under review after edits
add_action('um_user_edit_profile', 'um_post_edit_pending_hook', 10, 2);
function um_post_edit_pending_hook($user_id, $args){
if ( is_super_admin() ) {
return false;
} else {
global $ultimatemember;
$this->set_status('awaiting_admin_review');
}
}
I’ve also tried too many other variations to include and all of them break the site.
So, I’m asking the community for some support/ pointers on how to use the pending function without the email being sent or how to set the status to 'awaiting admin review' using my hook.
I’ve been using the UM github repository to help me research the UM code:
After quite a bit of further research I managed to identify the um_submit_form_profile action which is triggered when users edit their profile, but not used at registration, so the duplicate email issue at registration is solved.
Here is my original hook into the new action. This sets the user status to pending admin review when users edit their profile.
// Set profile to under pending after edits
add_action('um_submit_form_profile', 'um_post_edit_pending_hook', 10, 2);
function um_post_edit_pending_hook($user_id, $args){
if ( is_super_admin() ) {
return false;
} else {
global $ultimatemember;
$ultimatemember->user->pending();
}
}
Thanks to Champ Campo, one of the plugin authors, I got an even better fix that just changes the account status to awaiting admin review and does nothing else.
// Set profile to under review after edits
add_action('um_user_edit_profile', 'um_post_edit_pending_hook');
function um_post_edit_pending_hook( $args ){
$user_id = $args['user_id'];
if ( is_super_admin() ) {
return;
}
update_user_meta( $user_id, 'account_status', 'awaiting_admin_review');
}
I couldn't make this work in UM 2+. However, for anyone still struggling with this, I did find a way to do it, by tacking on the user meta change to the end of an email notification snippet which I found. I also adjusted the email to include the 'description' field from the profile, so admin can see immediately if it has been changed to include anything undesirable.
/*function to notify admin of profile changes*/
add_action( 'um_after_user_updated', 'my_after_user_updated', 10, 3 );
function my_after_user_updated( $user_id, $args, $userinfo ) {
um_fetch_user($user_id);
$groupMember = um_user('display_name');
$groupMmbr_name = um_user('user_login');
$groupMmbr_hidden = um_user('hide_in_members');
$groupMmbr_status = um_user('account_status');
$groupMmbr_desc = um_user('description');
$loggedIn_user = wp_get_current_user();
$loggedIn_userEml = $loggedIn_user->user_email;
$headers = array('Content-Type: text/html; charset=UTF-8', 'Cc:your-cc-address#yourwebsite.com', 'Bcc:',
'From:Your Website <website#yourwebsite.com>', 'Reply-To:No-reply Email<noreply#yourwebsitesite.com>');
wp_mail( 'your-admin-email-address#yourwebsite.com', 'The member profile '.$groupMember.' has been updated.',
'The <b>'.$groupMember.'</b> profile was updated by the user with this email address: '.$loggedIn_userEml.'. <a href="https://yourwebsite.com/member/'.$groupMmbr_name.'/?profiletab=main&um_action=edit"><br>
<b>Click here</b></a> to visit this profile online.<br><br><i style="color:#767676; font-size:11px; text-align:center;"><b>NOTE:</b> you must be logged in first to see this profile.</i>
<br><br>The new profile description is:<br><br>'.$groupMmbr_desc.'<br><br>',$headers);
update_user_meta( $user_id, 'account_status', 'awaiting_admin_review');
}
Related
I'm trying to deactivate the (TeraWallet) plugin for all user roles only allow the subscriber roles.
I'm using this code to deactivate the plugin for the customer role:
function desactivate_plugin_wallet()
{
global $current_user;
if (in_array('customer', $current_user->roles)) {
deactivate_plugins('/woo-wallet/woo-wallet.php');
} else {
activate_plugins('/woo-wallet/woo-wallet.php');
}
}
add_action('admin_init', 'desactivate_plugin_wallet');
And I applying the code to activate the theme dfunction.php file.
But the code not working.
Advance thank you to a great and senior developer to resolve the problem.
As I am testing from my end, It's working perfectly, My test code sample is:
function desactivate_plugin_wallet()
{
$myplugin = 'woo-wallet/woo-wallet.php';
if (current_user_can( 'administrator' )) {
activate_plugins($myplugin);
} else {
deactivate_plugins($myplugin);
}
}
add_action('admin_init', 'desactivate_plugin_wallet', 10, 2);
add_action('admin_init', 'my_filter_the_plugins');
function my_filter_the_plugins()
{
global $current_user;
if (in_array('customer', $current_user->roles)) {
deactivate_plugins( // deactivate for media_manager
array(
'/woo-wallet/woo-wallet.php'
),
true, // silent mode (no deactivation hooks fired)
false // network wide
);
} else { // activate for those than can use it
activate_plugins(
array(
'/woo-wallet/woo-wallet.php'
),
'', // redirect url, does not matter (default is '')
false, // network wise
true // silent mode (no activation hooks fired)
);
}
}
Basically this happens:
For the customer user group the my_filter_the_plugins disables(silently) the plugin. We then need to reactivate the plugin(silently, again) for those that aren't in the customer user group.
I have few WordPress websites with disabled registration, but still, I can see people are registering as admin, after a while, they reset the password and log in to the admin panel.. as I can see some fishy things on my server. How can I secure my websites from this kind of registration? the URL mydomain.comwp-login.php?action=register says disabled and redirecting to the login page.
Setting -> General -> uncheck "Anyone can register"
After successful registration, Wordpress immediately calls 'user_register' hook. You can perform a task there.
add_action( 'user_register', 'myplugin_registration_save', 10, 1 );
function myplugin_registration_save( $user_id ) {
/** Here You can disable user's status or change user's credentials on the behalf of '$user_id' so that it cannot be logged into your system. You can remove the user as well. */
}
If you are comfortable with editing your theme's function.php then these scripts will help:
Disable all user registrations:
If your site is not handling any memberships and you want to totally disable the user registrations, then you can add this script in your active themes function.php file:
add_filter( 'wp_pre_insert_user_data', 'disable_user_registrations', 10, 2 );
function disable_user_registrations ($data, $update) {
if( !$update ) {
return [];
}
return $data;
}
This will throw an error: 'Not enough data to create this user.'
Disable specific user roles:
For example, disable user registrations with administrator role:
add_filter( 'wp_pre_insert_user_data', 'disable_user_registrations_for_role', 10, 4 );
function disable_user_registrations_for_role ($data, $update, $userId, $userdata) {
if( !$update && !empty($userdata['role']) && $userdata['role'] == 'administrator' ) ) {
return [];
}
return $data;
}
Disable specific usernames:
If you would like to disable registrations with specific usernames such as admin, then you can use below code:
add_filter( 'illegal_user_logins', 'disable_user_registrations_with_usernames' );
function disable_user_registrations_with_usernames () {
return ['admin']; //disables anyone registering with the username admin
}
I found many questions like this but nothing matching to my requirement.Here my requirement is to lock a specific page named settings. It's not to be deleted by others.But it should be able to edit. Is there any way to lock a specific page using its page id or name.
Create a hook in themes function file as per below:
function restrict_page_deletion($post_ID){
$user = get_current_user_id();
$restricted_pageId = 4;
if($post_ID == $restricted_pageId)
{
echo "You are not authorized to delete this page.";
exit;
}
}
add_action('before_delete_post', 'restrict_page_deletion', 10, 1);
Pass your page id to a restricted_pageId variable.
If you want to implement this functionality for multiple pages then use the array in place of the variable.
Admin can move a page to trash but admin will not able to delete it.
If you want to block admin for trach functionality then call a hook on "wp_trash_post" action.
add_action('wp_trash_post', 'restrict_page_deletion', 10, 1);
function wpse_312694_restrict_page_deletion( $caps, $cap, $user_id, $args ) {
$post_id = $args[0];
if ( $cap === 'delete_post' && $post_id === 117 ) {
$caps[] = 'do_not_allow';
}
return $caps;
}
add_filter( 'map_meta_cap', 'wpse_312694_restrict_page_deletion', 10, 4 );
I currently have a WP site setup with a unique 'multisite' plugin installed specifically to allow for a single admin area of WooCommerce products, but with 2 different front-ends based on 2 different domains, with separate themes.
One of the sites is a 'wholesale' site while the other is 'retail'. The wholesale site should only allow trade customers to make purchases. The problem lies in that both sites are sharing a single domain, and therefore user accounts.
The problem: I need to ensure if a user who is does not have the user role 'trade_customer' tries to log into the wholesale site, the role is checked and the user is logged out, redirected to login page with a notification. So far I have the following in functions.php:
function trade_customers_only() {
function get_user_role() {
global $current_user;
$user_roles = $current_user->roles;
$user_role = array_shift($user_roles);
return $user_role;
}
$the_current_role = get_user_role();
echo $the_current_role;
if( $the_current_role != 'administrator' ) {
$logout_url = wp_login_url().'?mode=tradeonly';
wp_destroy_current_session();
wp_logout();
wp_redirect( $logout_url, 302 );
exit();
}
}
add_action('wp_login', 'trade_customers_only');
// CUSTOM LOGIN MESSAGES
function my_login_message() {
if( $_GET['mode'] == 'tradeonly' ){
$message = '<p class="message"><b>You must be a Trade Customer to access this site.</b></p>';
return $message;
}
}
add_filter('login_message', 'my_login_message');
This code is currently: returning the logged in user to wp-login.php and adding the note "You must be a trade customer... etc". However, after the first login attempt with any user role, every other login attempt does the same redirect and shows message. Is my code incorrect or is there some WP session cookie in the DB or browser causing the problem whereby WP thinks I am not using an admin account?
The first time I attempted login was with admin account. it worked and went to dashboard. Next attempt was with a customer role account. The redirect and note occurred. A following attempt with admin account only did the redirect with note, but no dashboard access.
1) Change your trade_customers_only function:
function trade_customers_only($login, $user) {
if( $user->roles && !in_array('administrator',$user->roles)) {
$logout_url = wp_login_url().'?mode=tradeonly';
wp_destroy_current_session();
wp_logout();
wp_redirect( $logout_url, 302 );
exit();
}
}
And fix your action call:
add_action('wp_login', 'trade_customers_only',10,2);
2) The other solution is using authenticate filter instead of using wp_login action. The difference is that you check for the user's role before user's session sets, so you don't need to destroy it.
add_filter('authenticate',function($user,$username) {
if (!is_wp_error($user)) {
$auth_user=get_user_by('login',$username);
if ($auth_user && !in_array('administrator',$auth_user->roles)) {
return new WP_Error('authentication_failed', '<p class="message"><b>You must be a Trade Customer to access Key Essentials. Are you looking for Love Tillys?</b></p>');
}
}
return $user;
},100,2);
My new full code is now:
function trade_customers_only($login, $user) {
if( $user->roles && !in_array('administrator',$user->roles)) {
$logout_url = wp_login_url().'?mode=tradeonly';
wp_destroy_current_session();
wp_logout();
wp_redirect( $logout_url, 302 );
exit();
}
}
add_action('wp_login', 'trade_customers_only',10,2);
// CUSTOM LOGIN MESSAGES
function my_login_message() {
if( $_GET['mode'] == 'tradeonly' ){
$message = '<p class="message"><b>You must be a Trade Customer to access this site.</b></p>';
return $message;
}
}
add_filter('login_message', 'my_login_message');
This code works properly. However as Kulivov Sergey mentioned in his reply, using the authenticate filter instead of the wp_login action is better for what I need to achieve. Using:
add_filter('authenticate',function($user,$username) {
if (!is_wp_error($user)) {
$auth_user=get_user_by('login',$username);
if ($auth_user && !in_array('administrator',$auth_user->roles)) {
return new WP_Error('authentication_failed', '<p class="message"><b>You must be a Trade Customer to access this site.</b></p>');
}
}
return $user;
},100,2);
Not only checks for the user role without logging in and creating a session, it also keeps the user on their current page with no redirection, which is great.
I have tested the below code as working correctly.
There's no need to run wp_destroy_current_session() or wp_logout(), just simply return an error instead and it will interrupt authentication and show your error message on the login page.
You might have to make sure the priority is last (100 in this case), so that existing filters wp_authenticate_username_password, wp_authenticate_email_password and wp_authenticate_spam_check all do their thing and before the user is fully logged in that you will then deny.
/* Only allow administrators to login */
add_filter( 'authenticate', 'my_admin_check', 100, 1 );
function my_admin_check( $user ) {
// Make sure this is a real login attempt, without errors
if ( !is_wp_error($user) ) {
$user_role = $user->roles[0];
// add or remove the roles you want to allow/disallow (can be a custom role or regular WordPress roles)
if ( !in_array( $user_role, array( 'trade_customer' ) ) ){
return new WP_Error( 'login_failed', __( "Only staff can use this login.", "mysite_domain" ) );
} else {
// allow the login
return $user;
}
} else {
// We're just loading the login page, not running a login.
return $user;
}
}
Hey guys I have a cash on delivery payment method on my wordpress/woocomerce website that I want to hide from the customer user role and non-logged in users.
I've been searching up and down and the only thing I found close was this bit of code.
function paypal_disable_manager( $available_gateways )
{global $woocommerce;
if ( isset( $available_gateways['paypal'] ) && current_user_can('customer') ) {
unset( $available_gateways['paypal'] );
}
return $available_gateways;
}
add_filter( 'woocommerce_available_payment_gateways','paypal_disable_manager' );
Would someone be able to help me modify this code to make it work for my use. Thank you in advance!
Have mention the code which is tried and tested for you. It works well. Lemme know if the same works for you too.
function wdm_disable_cod( $available_gateways ) {
//check whether the avaiable payment gateways have Cash on delivery and user is not logged in or he is a user with role customer
if ( isset($available_gateways['cod']) && (current_user_can('customer') || ! is_user_logged_in()) ) {
//remove the cash on delivery payment gateway from the available gateways.
unset($available_gateways['cod']);
}
return $available_gateways;
}
add_filter('woocommerce_available_payment_gateways', 'wdm_disable_cod', 99, 1);
<?php
//--- Filter for remove any payment gateway as per the user role selected --
add_filter('woocommerce_available_payment_gateways','filter_gateways',1);
function filter_gateways($gateways){
global $woocommerce, $current_user;
if ( is_user_logged_in() ) {
$userRole = implode(',',$current_user->roles);
if($userRole == 'my_user_role'){
//-- Remove casho on delivery if following user have logged in
unset($gateways['cod']);
}
}else{
//-- Hide COD if user not logged in
unset($gateways['cod']);
}
return $gateways;
}
?>
//-- Try this one, I have already make use of this code against minimum order limit