Conditionally updating roles in WordPress - wordpress

I actually want to create an easy function but it doesn't seem to work.
I want that when a user logs to his account on Wordpress to change his role (subscriber -> directory_1) on some condition (easy in this case to test, it should change everytime, but still not working).
Here is my code :
add_action('wp_login', 'update_roles');
function update_roles()
{
global $wpdb;
$author = wp_get_current_user();
if(current_user_can('subscriber'))
{
$author->remove_role( 'subscriber' );
$author->add_role( 'directory_1' );
}
}
Thanks for the help!

You should be using wp_update_user() to update a user's role. After you have added a role using add_role(), you can do something like this:
function custom_update_roles( $user_login, $user ) {
if ( ! empty( $user->roles ) && is_array( $user->roles ) ) {
if ( in_array( "subscriber", $user->roles ) ) {
$user_id = wp_update_user( array( 'ID' => $user->ID, 'role' => 'directory_1' ) );
if ( is_wp_error( $user_id ) ) {
// Error.
} else {
// Success.
}
} else {
// This user is not a subscriber.
}
}
}
add_action( 'wp_login', 'custom_update_roles', 10, 2 );
Refs:
http://codex.wordpress.org/Function_Reference/wp_update_user
http://codex.wordpress.org/Function_Reference/add_role

Related

Woocommerce role per product [duplicate]

In woocommerce I am trying to change the user role depending on customer purchased products. I saw the various code and tried them all without being able to make them work.
I have several products to check for different user roles change.
This is my code attempt:
add_action('woocommerce_order_status_completed', 'change_role_on_purchase' );
$products_to_check = array( '5345, 5344,5342' );
foreach ( $items as $item ) {
if ( $order->user_id > 0 && in_array( $item['product_id'], $products_to_check ) ) {
$user = new WP_User( $order->user_id );
// Change role
$user->remove_role( 'Subscriber' );
$user->add_role( 'Student-Group' );
// Exit the loop
break;
}
}
$products_to_check = array( '5353, 5352,5351,12119' );
foreach ( $items as $item ) {
if ( $order->user_id > 0 && in_array( $item['product_id'], $products_to_check ) ) {
$user = new WP_User( $order->user_id );
// Change role
$user->remove_role( 'Subscriber' );
$user->add_role( 'Student-11free2' );
// Exit the loop
break;
}
}
$products_to_check = array( '5360, 5359,5358' );
foreach ( $items as $item ) {
if ( $order->user_id > 0 && in_array( $item['product_id'], $products_to_check ) ) {
$user = new WP_User( $order->user_id );
// Change role
$user->remove_role( 'Subscriber' );
$user->add_role( 'Student-11free3' );
// Exit the loop
break;
}
}
$products_to_check = array( '5363, 5362,5361' );
foreach ( $items as $item ) {
if ( $order->user_id > 0 && in_array( $item['product_id'], $products_to_check ) ) {
$user = new WP_User( $order->user_id );
// Change role
$user->remove_role( 'Subscriber' );
$user->add_role( 'Student-11regular2' );
// Exit the loop
break;
}
}
But it doesn't work. Any help will be appreciated.
Since Woocommerce 3 your code is outdated and full of mistakes… Instead use the following:
add_action('woocommerce_order_status_completed', 'change_user_role_on_order_status_completed', 10, 2 );
function change_user_role_on_order_status_completed( $order_id, $order ){
if ( $order->get_user_id() > 0 ) {
// Here your settings in this multi dimensional array
$user_roles_for_products = array(
'Student-Group' => array( 5345, 5344, 5342 ),
'Student-11free3' => array( 5353, 5352, 5351, 12119 ),
'Student-11free3' => array( 5360, 5359, 5358 ),
'Student-11regular2' => array( 5363, 5362, 5361 ),
);
$user = $order->get_user();
// Loop through order items
foreach ( $order->get_items() as $item ) {
$product_ids = array( $item->get_product_id(), $item->get_variation_id() );
// Loop through all products to check
foreach ( $user_roles_for_products as $role => $products_to_check ) {
if ( array_intersect( $product_ids, $products_to_check ) && in_array( 'Subscriber', $user->roles ) ) {
$user->remove_role( 'Subscriber' );
$user->add_role( $role );
$break = true;
break; // Stop the loop
}
}
if( isset($break) && $break )
break; // Stop the loop
}
}
}
Code goes in function.php file of your active child theme (or active theme). It should better works.

Wordpress add_filter use variable

I'm using Awesome Support and I want to add a filter to manually assign the agent to answer the tickets.
This is the funcition:
function wpas_find_agent( $ticket_id = false ) {
if ( defined( 'WPAS_DISABLE_AUTO_ASSIGN' ) && true === WPAS_DISABLE_AUTO_ASSIGN ) {
return apply_filters( 'wpas_find_available_agent', wpas_get_option( 'assignee_default' ), $ticket_id );
}
$users = shuffle_assoc( wpas_get_users( apply_filters( 'wpas_find_agent_get_users_args', array( 'cap' => 'edit_ticket' ) ) ) );
$agent = array();
foreach ( $users->members as $user ) {
$wpas_agent = new WPAS_Member_Agent( $user );
/**
* Make sure the user really is an agent and that he can currently be assigned
*/
if ( true !== $wpas_agent->is_agent() || false === $wpas_agent->can_be_assigned() ) {
continue;
}
$count = $wpas_agent->open_tickets(); // Total number of open tickets for this agent
if ( empty( $agent ) ) {
$agent = array(
'tickets' => $count,
'user_id' => $user->ID,
);
} else {
if ( $count < $agent['tickets'] ) {
$agent = array(
'tickets' => $count,
'user_id' => $user->ID,
);
}
}
}
if ( is_array( $agent ) && isset( $agent['user_id'] ) ) {
$agent_id = $agent['user_id'];
} else {
$default_id = wpas_get_option( 'assignee_default', 1 );
if ( empty( $default_id ) ) {
$default_id = 1;
}
$agent_id = $default_id;
}
return apply_filters( 'wpas_find_available_agent', (int) $agent_id, $ticket_id );
}
And this is the filter I want to add:
add_filter('wpas_find_available_agent', 'asignar_agente', 10, 2);
function asignar_agente($agent_id){
$term_list = wp_get_post_terms( $ticket_id, 'department', array( 'fields' => 'ids' ) );
if($term_list[0] == 34){
$agent_id = 2;
}else{
$agent_id = 3;
}
return $agent_id;
}
How can I pass the $ticket_id variable to the filter to use it?
I need this variable because I need to know the term (department taxonomy) of the ticket is being submitted.
Thank you.
Since you pass $ticket_id when you call apply_filters('wpas_find_available_agent'....); you will be able to get the $ticket_id if you change your filter function to.
function asignar_agente($agent_id, $ticket_id){ <--- just add this parameter here
...
}
this is possible since you pass the parameter in apply_filters and you say add_filter('wpas_find_available_agent', 'asignar_agente', 10, 2); with emphasis on the last parameter with the value 2, that means your filter function will be able to receive 2 parameters.

How to disable admin login from front end?

I'm trying to disable admin login from front end of my wordPress site but my backend login also gets disable both login shows admin cannot login here
<?php
add_filter( 'authenticate', 'wp_admin_prevent_authentication', 30, 3 );
function wp_admin_prevent_authentication( $user, $username, $password ) {
if ( $user instanceof WP_User && is_page( 'my-account' ) ) {
if ( array_intersect( (array) $user->roles, [ 'administrator' ] ) ) {
return new WP_Error( 'admin-error', 'Admins cannot login from here.' );
};
};
return $user;
};
Not sure you can use is_page() inside authenticate but you can get page name using $_SERVER['REQUEST_URI']. check the below code.
function wp_admin_prevent_authentication( $user, $username, $password ) {
$url = explode( '/', rtrim( $_SERVER['REQUEST_URI'], '/') );
// If in My account dashboard page
if( $user instanceof WP_User && end( $url ) == 'my-account' ){
if ( array_intersect( (array) $user->roles, [ 'administrator' ] ) ) {
return new WP_Error( 'admin-error', 'Admins cannot login from here.' );
}
}
return $user;
}
add_filter( 'authenticate', 'wp_admin_prevent_authentication', 30, 3 );
Tested and works.
You can try with the below code, maybe it will work for you.
function wpum_admin_prevent_authentication( $user, $username, $password ) {
if ( $user instanceof WP_User && is_page( wpum_get_core_page_id( 'login' ) ) ) {
if ( array_intersect( (array) $user->roles, [ 'administrator' ] ) ) {
return new WP_Error( 'admin-error', 'Admins cannot login from here.' );
}
}
return $user;
}
add_filter( 'authenticate', 'wpum_admin_prevent_authentication', 30, 3 );

Update Username (User_Login) on Email Change (WooCommerce)

A number of questions have been raised on StackOverflow in regards to using email address as username when registering via My Account. I have the working code included below.
$this->loader->add_filter('pre_user_login', $plugin_public, 'audp_wc_register_email_as_username' );
public function audp_wc_register_email_as_username( $user_login ) {
if ( isset ( $_POST['email'] ) ) {
$user_login = $_POST['email'];
}
return $user_login;
}
I've updated my own question with the following code to update the user_login details.
$this->loader->add_action( 'woocommerce_save_account_details', $plugin_public, 'audp_wc_update_email_and_username', 20, 1 );
public function audp_wc_update_email_and_username() {
if ( isset( $_POST['account_email'] ) ) {
global $wpdb;
$user_id = get_current_user_id();
$new_login = $_POST['account_email'];
// Update user user_login
$wpdb -> update( $wpdb -> users,
array( 'user_login' => $new_login, 'user_nicename' => $new_nicename ),
array( 'ID' => $user_id )
);
}
// Update nickname
update_user_meta( $user_id, 'nickname', $new_login );
}
I've updated the question to include the full code. Because we are dealing with user_login we cannot use wp_update_user(), I have used the class description above, but the below code is standard (non-class) functions.
add_action( 'woocommerce_save_account_details', 'audp_wc_update_email_and_username', 20, 1 );
function audp_wc_update_email_and_username() {
if ( isset( $_POST['account_email'] ) ) {
global $wpdb;
$user_id = get_current_user_id();
$new_login = $_POST['account_email'];
// Update user user_login
$wpdb -> update( $wpdb -> users,
array( 'user_login' => $new_login, 'user_nicename' => $new_nicename ),
array( 'ID' => $user_id )
);
// Update nickname
update_user_meta( $user_id, 'nickname', $new_login );
}

How to redirect user after success login to admin dashboard in multisite of wordpress

After successful login user redirect to home url but i want to redirect it to admin dashboard after successful login in wordpress.
Note:I use multisite network. Any idea?
This can be used for wordpress multisite. It will direct user roles and redirect to specific page.
function login_redirect_page( $redirect_to, $request, $user ) {
global $user;
if ( isset( $user->roles ) && is_array( $user->roles ) ) {
if ( in_array( 'administrator', $user->roles ) ) {
return get_site_url().'/wp-admin/';
} else {
return home_url();
}
} else {
return $redirect_to;
}
}
add_filter( 'login_redirect', 'login_redirect_page', 10, 3 );
You can get the plugins on wordpress.org also.
function login_redirect_page( $redirect_to, $request, $user ) {
global $user;
if ( isset( $user->roles ) && is_array( $user->roles ) ) {
if ( in_array( 'administrator', $user->roles ) ) {
return get_site_url().'/wp-admin/';
}
if ( in_array( 'subscriber', $user->roles ) ) {
return get_site_url().'/wp-admin/';
}else {
return home_url();
}
} else {
return $redirect_to;
}
}
add_filter( 'login_redirect', 'login_redirect_page', 10, 3 );

Resources