I want to add column to show the customer role on the WooCommerce orders, I search and everything I found is for one user. I also found this code on this link (WooCommerce show custom column) but I do not understand where I put what I need.
I also found this code (https://gist.github.com/corsonr/5975207)
but I do not managed to get the user role.
I added $user_role = $user->roles;
and
switch ($column)
{
case "user_role":
echo $user_role;
break;
}
but it not worked, I know it is array but use of [0] or [1] did not work.
I missing something?
It is possible to do what I what?
Add below code in your theme functions.php
add_filter('manage_edit-shop_order_columns', 'add_column_heading', 20, 1);
function add_column_heading($array) {
$res = array_slice($array, 0, 2, true) +
array("customer_role" => "Customer Role") +
array_slice($array, 2, count($array) - 1, true);
return $res;
}
add_action('manage_posts_custom_column', 'add_column_data', 20, 2);
function add_column_data($column_key, $order_id) {
// exit early if this is not the column we want
if ('customer_role' != $column_key) {
return;
}
$customer = new WC_Order( $order_id );
if($customer->user_id != ''){
$user = new WP_User( $customer->user_id );
if ( !empty( $user->roles ) && is_array( $user->roles ) ) {
foreach ( $user->roles as $role )
echo $role;
}
}
}
Related
I added a custom filter to my functions.php file. When I first loaded it up which was a few versions of Woocommerce ago it worked perfectly.
Now it seems that all users are registered as the default 'customer' as opposed to 'student' when their emails do contain .ac.uk or .sch.uk
The filter function is as follows:
add_filter( 'woocommerce_new_customer_data', 'student_role', 10, 1 );
function student_role( $new_cust_data ) {
if ( strpos($new_cust_data['user_email'], '.ac.uk' ) >= 1 ) {
$new_cust_data['role'] = 'student';
}
elseif ( strpos($new_cust_data['user_email'], '.sch.uk') >= 1 ) {
$new_cust_data['role'] = 'student';
}
else {
$new_cust_data['role'] = 'customer';
}
return $new_cust_data;
}
Any help?
Try to replace >= 1 with !== false in your code (also it can be simplified) as follows:
add_filter( 'woocommerce_new_customer_data', 'set_new_customer_user_role_conditionaly' );
function set_new_customer_user_role_conditionaly( $args ) {
if ( strpos($args['user_email'], '.ac.uk') !== false || strpos($args['user_email'], '.sch.uk') !== false ){
$args['role'] = 'student';
}
return $args;
}
It should work.
I would like to prevent (make these fields readonly, for example) users from changing their billing information on the WooCommerce checkout form.
I'm currently using this code snippet:
add_filter('woocommerce_billing_fields', 'mycustom_woocommerce_billing_fields', 10, 1 );
function mycustom_woocommerce_billing_fields($fields)
{
$fields['billing_first_name']['custom_attributes'] = array('readonly'=>'readonly');
$fields['billing_last_name']['custom_attributes'] = array('readonly'=>'readonly');
$fields['billing_email']['custom_attributes'] = array('readonly'=>'readonly');
$fields['billing_phone']['custom_attributes'] = array('readonly'=>'readonly');
return $fields;
}
But the problem is: If the user has not filled in any of these fields in the registration, he is unable to insert his data in the checkout form because these fields are not editable.
My question is:
If the fields are not empty, how to make them readonly (or disabled)
Someone who can help me with this?
The answer of 7uc1f3r certainly works getting the user data… But since WooCommerce 3, you can use WC_Checkout get_value() dedicated method as follow:
add_filter( 'woocommerce_billing_fields', 'filter_wc_billing_fields', 10, 1 );
function filter_wc_billing_fields( $fields ) {
// On checkout and if user is logged in
if ( is_checkout() && is_user_logged_in() ) {
// Define your key fields below
$keys_fields = ['billing_first_name', 'billing_last_name', 'billing_email', 'billing_phone'];
// Loop through your specific defined fields
foreach ( $keys_fields as $key ) {
// Check that a value exist for the current field
if( ( $value = WC()->checkout->get_value($key) ) && ! empty( $value ) ) {
// Make it readonly if a value exist
$fields[$key]['custom_attributes'] = ['readonly'=>'readonly'];
}
}
}
return $fields;
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.
If you want this code to be also active in My account > Addresses > edit…, you will just have to remove is_checkout() && from the first IF statement.
I believe this is what you are looking for, comment with explanation added in code
function mycustom_woocommerce_billing_fields( $fields ) {
// Get current user
$user = wp_get_current_user();
// User id
$user_id = $user->ID;
// User id is found
if ( $user_id > 0 ) {
// Fields
$read_only_fields = array ( 'billing_first_name', 'billing_last_name', 'billing_email', 'billing_phone' );
// Loop
foreach ( $fields as $key => $field ) {
if( in_array( $key, $read_only_fields ) ) {
// Get key value
$key_value = get_user_meta($user_id, $key, true);
if( strlen( $key_value ) > 0 ) {
$fields[$key]['custom_attributes'] = array(
'readonly'=>'readonly'
);
}
}
}
}
return $fields;
}
add_filter('woocommerce_billing_fields', 'mycustom_woocommerce_billing_fields', 10, 1 );
In Woocommerce, I have code that changes the role if the user buys a certain product.
add_action( 'woocommerce_order_status_processing', 'change_role_on_purchase' );
function change_role_on_purchase( $order_id ) {
$order = new WC_Order( $order_id );
$items = $order->get_items();
foreach ( $items as $item ) {
$product_name = $item['name'];
$product_id = $item['product_id'];
$product_variation_id = $item['variation_id'];
if ( $order->user_id > 0 && $product_id == '3422, 3423, 3424' ) {
update_user_meta( $order->user_id, 'paying_customer', 1 );
$user = new WP_User( $order->user_id );
// Remove role
$user->remove_role( 'customer' );
// Add role
$user->add_role( 'subscriber' );
}
}
}
I need to, after logging in to the site, if the user "Subscriber" and he has a certain "Subscription" product in the cart, then the system redirects it to the checkout page.
I shall be very glad of your help!
Update: I will keep this variant. It can help other users.
add_filter('login_redirect', 'my_login_redirect', 10, 3);
function my_login_redirect($redirect_to, $request, $user)
{
global $woocommerce;
$items = $woocommerce->cart->get_cart();
$ids_to_check = array(3422, 3423, 3424);
foreach ($items as $item => $values) {
$product_id = wc_get_product($values['data']->get_id());
if (in_array($product_id, $id_to_check)) {
//is there a user to check?
if (isset($user->roles) && is_array($user->roles)) {
//check for subscribers
if (in_array('subscriber', $user->roles)) {
// redirect them to another URL, in this case, the homepage
$url = get_permalink(get_option('woocommerce_checkout_page_id'));
$redirect_to = $url;
}
}
}
}
return $redirect_to;
}
Your if statement will never return true, because you checking the product id if they are equal to '3422, 3423, 3424' which your product will never be equal to this what you need to do is store those ids in array and check if the product id in the array and if yes execute your code.
try the following:
add_action('woocommerce_order_status_processing', 'change_role_on_purchase');
function change_role_on_purchase($order_id)
{
$order = new WC_Order($order_id);
$items = $order->get_items();
$ids_to_check = array(3422, 3423, 3424, 15);
foreach ($items as $item) {
$product_name = $item['name'];
$product_id = $item['product_id'];
$product_variation_id = $item['variation_id'];
if (in_array($product_id, $id_to_check) && $order->user_id > 0) {
update_user_meta($order->user_id, 'paying_customer', 1);
$user = new WP_User($order->user_id);
// Remove role
$user->remove_role('customer');
// Add role
$user->add_role('subscriber');
}
}
}
To redirect the user if they have certain role you can use the following if you are using Woocommerce login page:
add_filter('woocommerce_login_redirect', 'my_login_redirect', 20, 2);
function my_login_redirect($redirect, $user)
{
if (in_array('subscriber', $user->roles)) {
// redirect them to another URL, in this case, the homepage
$url = get_permalink(get_option('woocommerce_checkout_page_id'));
$redirect = $url;
}
return $redirect;
}
if you are using WordPress Default login form you can use the following function:
add_filter('login_redirect', 'my_login_redirect', 20, 3);
function my_login_redirect($redirect_to, $request, $user)
{
//is there a user to check?
if (isset($user->roles) && is_array($user->roles)) {
//check for subscribers
if (in_array('subscriber', $user->roles)) {
// redirect them to another URL, in this case, the homepage
$url = get_permalink(get_option('woocommerce_checkout_page_id'));
$redirect_to = $url;
}
}
return $redirect_to;
}
Please keep in mind that woocommerce_order_status_processing does NOT guarantee that the order has been paid for. It simply means what it says. If you change the user role based on an open order, you open yourself to the risk that customers whose payment hasn't gone through do have access to whatever you are offering by changing the user role.
I have completed a woocommerce website for a client. As per the client requirement I got an issue. My client wants their agents just need to able to search for the orders but they should not able to edit any of the order or they should not see any other option. Agents should see all the order details like phone number, email and complete billing address but they should not able to edit anything.
I have tried few user role editors none of them giving that option.
Note : All the orders are guest orders only!
Please let me know if you have any idea how to achieve this.
Try this in your theme functions.php
//mydomain.com/my-account/view-order/xxxx - any order number here
function my_customer_has_capability( $allcaps, $caps, $args ) {
if ( isset( $caps[0] ) ) {
switch ( $caps[0] ) {
case 'view_order' :
$user_id = $args[1];
$order = wc_get_order( $args[2] );
if ( $order && $user_id == $order->user_id || my_get_current_user_role() == 'editor') {
$allcaps['view_order'] = true;
}
break;
}
}
return $allcaps;
}
add_filter( 'user_has_cap', 'my_customer_has_capability', 10, 3 );
function my_get_current_user_role() {
$current_user = wp_get_current_user();
if ( !($current_user instanceof WP_User) )
return;
if( empty($current_user->roles[0]) )
return false;
$role = ($current_user->roles[0]);
return (string)$role;
}
I have a product on my site that allows users to select what items they would like included with their order from a list of product addons. The default is 0 and the user can input any number to include that addon in their order.
I'm using the following code to successfully filter out all addons with a value of 0 from the shopping cart and the order confirmation page. But I cannot figure out how to filter them out of the order details in the admin area or from the admin and customer emails. Hoping someone here will have some answers/direction for me.
add_filter( 'woocommerce_order_get_items', 'custom_order_items', 10, 2 );
function custom_order_items( $order_meta ) {
reset($order_meta);
$first_key = key($order_meta);
$search_term = 'Basket Items - ';
$order = reset($order_meta);
if( is_array($order['item_meta']) ) {
foreach ( $order['item_meta'] as $key => $value ) {
if (strpos($key, $search_term) !== false && $value[0] == 0) {
unset($order['item_meta'][$key]);
}
}
$order_meta[$first_key] = $order;
}
return $order_meta;
}
After trying dozens of Woocommerce filters I finally figured out a solution to this problem. By filtering the product array when adding products to the cart I was able to successfully filter out addons that had a value of 0.
add_filter( 'woocommerce_add_cart_item', 'custom_function', 10, 2 );
function custom_function( $item ) {
$addons = $item['addons'];
foreach( $addons as $key => $value) {
if( $value['value'] === 0 ) {
unset($addons[$key]);
}
}
$item['addons'] = $addons;
return $item;
}