Use CRUD in Woocommerce loop to get custom meta field

6. September 2022

foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
			$product = $cart_item['data'];
			if ( $product->is_type( [ 'variation' ] ) ) {
				$product = wc_get_product( $product->get_parent_id() );
			}

			$custom_meta_product = $product->get_meta( '_custom_meta_product', true );


			if ( $custom_meta_product ) {
				return true;
			}
		}
Create a product meta and verify nonce PHPCS way

6. September 2022

/**
 * Adds custom field to General tab in Product data
 */
function woocommerce_new_price() {
	woocommerce_wp_text_input(
		[
			'id' => '_new_product_price',
			'placeholder' => '',
			'label' => __( 'New price', 'two' ),
			'type' => 'number',
		]
	);
}
add_action( 'woocommerce_product_options_general_product_data', 'woocommerce_new_price' );

/**
 * Saves new price when product is saved/updated
 */
function save_woocommerce_new_price( $post_id ) {
	$nonce = wp_create_nonce( '_new_product_price' );
	if ( empty( $nonce ) || ! wp_verify_nonce( wp_unslash( $nonce ), '_new_product_price' ) ) {
			return;
	}
	$product = wc_get_product( $post_id );
	$new_price = ! empty( sanitize_key( wp_unslash( $_POST['_new_product_price'] ) ) ) ? sanitize_key( wp_unslash( $_POST['_new_product_price'] ) ) : '';
	$product->update_meta_data( '_new_product_price', esc_attr( $new_price ) );
	$product->save();
}
add_action( 'woocommerce_process_product_meta', 'save_woocommerce_new_price' );
Overwrite prices in catalog and product page

10. August 2022

/**
 * Overwrite Sale price with custom price
 */
function overwrite_sale_price_with_custom_price ( $price, $product ) {
	if ( $custom_price ) :
		$price = wc_format_sale_price( wc_get_price_to_display( $product, array( 'price' => $product->get_regular_price() ) ), $product->get_meta('_custom_price') ) .
		$product->get_price_suffix();
	endif;

	return $price;
}
add_filter( 'woocommerce_get_price_html', 'overwrite_sale_price_with_custom_price', 10, 2 );
Add custom ACF field to Woo Attributes

10. November 2021

// Adds a custom rule type.
add_filter( 'acf/location/rule_types', function( $choices ){
    $choices[ __("Other",'acf') ]['wc_prod_attr'] = 'WC Product Attribute';
    return $choices;
} );

// Adds custom rule values.
add_filter( 'acf/location/rule_values/wc_prod_attr', function( $choices ){
    foreach ( wc_get_attribute_taxonomies() as $attr ) {
        $pa_name = wc_attribute_taxonomy_name( $attr->attribute_name );
        $choices[ $pa_name ] = $attr->attribute_label;
    }
    return $choices;
} );

// Matching the custom rule.
add_filter( 'acf/location/rule_match/wc_prod_attr', function( $match, $rule, $options ){
    if ( isset( $options['taxonomy'] ) ) {
        if ( '==' === $rule['operator'] ) {
            $match = $rule['value'] === $options['taxonomy'];
        } elseif ( '!=' === $rule['operator'] ) {
            $match = $rule['value'] !== $options['taxonomy'];
        }
    }
    return $match;
}, 10, 3 );

This goes to functions.php and afterwards will be visible in Custom Fields where you set where the custom field should be visible

Redirect after login to My Account

29. March 2021

function twstudio_customer_login_redirect( $redirect, $user ) {
    if ( wc_user_has_role( $user, 'customer' ) ) {
        $redirect = '/meine-seite/edit-account/'; 
    }
    return $redirect;
}
add_filter( 'woocommerce_login_redirect', 'twstudio_customer_login_redirect', 9999, 2 );

Add extra field to check-out

9. March 2021

/**
 * Add an extra field in checkout (VAT)
 */
function twstudio_custom_override_checkout_fields( $fields ) {
    $fields['billing']['billing_vat'] = array(
        'label'     => __('VAT', 'woocommerce'),
        'placeholder'   => _x('', 'placeholder', 'woocommerce'),
        'required'  => false,
        'class'     => array('form-row-wide'),
        'clear'     => true
    );
    return $fields;
}
add_filter( 'woocommerce_checkout_fields' , 'twstudio_custom_override_checkout_fields' );

// Display field value (VAT) on the order edit page
function custom_checkout_field_display_admin_order_meta($order){
    echo '<p><strong>'.__('VAT').':</strong> ' . get_post_meta( $order->get_id(), '_billing_vat', true ) . '</p>';
}
add_action( 'woocommerce_admin_order_data_after_shipping_address', 'custom_checkout_field_display_admin_order_meta', 10, 1 );
Add coupon code on order confirmation mail (to admin)

5. March 2021

/**
 * Add used coupons to the order confirmation email
 */
function twstudio_add_payment_method_to_admin_new_order( $order, $is_admin_email ) {

    if ( $is_admin_email ) {
        if( $order->get_used_coupons() ) {
            $coupons_count = count( $order->get_used_coupons() );
            $i = 1;
            $coupons_list = '';
            foreach( $order->get_used_coupons() as $coupon) {
                $coupons_list .=  $coupon;
                if( $i < $coupons_count )
                    $coupons_list .= ', ';
                $i++;
            }
            echo '<p><strong>Kuponger brukt (' . $coupons_count . ') :</strong> ' . $coupons_list . '</p>';
        } 
    } 
}

add_action( 'woocommerce_email_after_order_table', 'twstudio_add_payment_method_to_admin_new_order', 15, 2 );
Add text string in front of subject on New Order mail on local pickup.

11. February 2021

/*
 * Add text string in front of subject on New Order mail.
 */
function twstudio_change_admin_email_subject( $subject, $order ) {
    global $woocommerce;
    $blogname = wp_specialchars_decode(get_option('blogname'), ENT_QUOTES);
    $subject = sprintf( '[%s] Ny kundeordre (# %s) - %s', $blogname, $order->id, $order->order_date );

    $shipping_method = @array_shift($order->get_shipping_methods());
    if ( $shipping_method ) {
        $shipping_method_id = $shipping_method['method_id'];

        // local_pickup
        if ( strpos($shipping_method_id, 'local_pickup' ) !== false ) {
            $subject = sprintf( 'CUSTOM TEXT [%s] Ny kundeordre (%s) - %s', $blogname, $order->id, $order->get_date_created()->format ('d.m.Y') );
        }
    }

    return $subject;
}
add_filter('woocommerce_email_subject_new_order', 'twstudio_change_admin_email_subject', 1, 2);
Related products useful functions

6. January 2021

/**
 * Change number of related products output
 */
function woo_related_products_limit() {
    global $product;

    $args['posts_per_page'] = 6;
    return $args;
}
function twstudio_related_products_args( $args ) {
    $args['posts_per_page'] = 5; // 5 related products
    $args['columns'] = 2; // arranged in 2 columns
    return $args;
}
add_filter( 'woocommerce_output_related_products_args', 'twstudio_related_products_args', 20 );



/**
 * Remove category from Related products
 */
function twstudio_exclude_product_category_from_related_products( $related_posts, $product_id, $args  ){
    $term_slug = 'ukategorisert';

    $exclude_ids = wc_get_products( array(
        'status'    => 'publish',
        'limit'     => -1,
        'category'  => array($term_slug),
        'return'    => 'ids',
    ) );

    return array_diff( $related_posts, $exclude_ids );
}
add_filter( 'woocommerce_related_products', 'twstudio_exclude_product_category_from_related_products', 10, 3 );

Change ‘landingpage’ in My Account

13. August 2020

**
 * Change landingpage on My account page
 */
function twstudio_subscriptions_as_myaccount_home(){
	if ( is_account_page() && empty( WC()->query->get_current_endpoint() ) ){
		wp_safe_redirect( wc_get_account_endpoint_url( 'subscriptions' ) );
		exit;
	}
}
add_action( 'template_redirect', 'twstudio_subscriptions_as_myaccount_home' );

Goes into functions.php. Change ‘subscriptions’ to your endpoint of choise.

Replace ‘Dismiss’ with an X in Woo store notice

2. April 2020

function twstudio_demo_store_filter($text) {

	$text = str_replace(array('<p class="woocommerce-store-notice demo_store">', '</p>', 'Dismiss'), array('<div class="woo-notice-container"><p class="woocommerce-store-notice demo_store">', '</p></div>', 'X'), $text);
	return $text;
}
add_filter('woocommerce_demo_store', 'twstudio_demo_store_filter', 10, 1);
Remove Uncategorized from widget

20. March 2020

function remove_uncategorized_category( $terms, $taxonomy, $query_vars, $term_query ) {
if ( is_admin() )
return $terms; if ( $taxonomy[0] == 'product_cat' ) {
foreach ( $terms as $k => $term ) {
if ( $term->term_id == get_option( 'default_product_cat' ) ) {
unset( $terms[$k] );
}
}
} return $terms;
}
add_filter( 'get_terms', 'remove_uncategorized_category', 10, 4 );
Add a empty cart button to cart page

6. February 2020

// Adds a EMPTY CART button to cart
add_action( 'init', 'woocommerce_clear_cart_url' );
function woocommerce_clear_cart_url() {
	global $woocommerce;

	if ( isset( $_GET['empty-cart'] ) ) {
		$woocommerce->cart->empty_cart();
	}
}

add_action( 'woocommerce_cart_actions', 'tws_add_clear_cart_button', 20 );
function tws_add_clear_cart_button() {
	echo "<a class='button empty-button' href='?empty-cart=true'>" . __( 'Tøm handlekurv', 'woocommerce' ) . "</a>";
}
Remove surname from comments

2. December 2019

Change of this field: .woocommerce-review__author

/**
 * Change the comment name to show only Firstname.
 */
function twstudio_my_comment_author( $author = '' ) {

	$comment = get_comment( $comment_ID );
	if ( ! empty( $comment->comment_author ) ) {
		if ( $comment->user_id > 0 ) {
			$user   = get_userdata( $comment->user_id );
			$author = $user->first_name . ' ' . substr( $user->last_name, 0, 0 ) . '';
		} else {
			$author = __( 'No name' );
		}
	}

	return $author;
}

add_filter( 'get_comment_author', 'twstudio_my_comment_author', 10, 1 );
Add custom field to the ‘My Account’

13. March 2019

function my_accout_custom_text_field(){
	$user_id = get_current_user_id();
	$custom_user_text = get_field('tekstfelt', 'user_' . $user_id );
	if ( $custom_user_text ) {
		echo '<div class="custom-text-field">';
		echo $custom_user_text;
		echo '</div>';
	}
}
add_action( 'woocommerce_account_content', 'my_accout_custom_text_field', 9 );

Remember to create a new ACF field and set the Location to ‘User Form is equal to Add /edit’ (‘Brukerskjema er lik Legg til / Rediger’)

Change WooCommerce Email style

22. August 2018

 

/**
 * Change WooCommerce Email Styles
 */
function twstudio_woocommerce_email_styles( $css ) {
   $css .= "
   
   //Custom css goes here

   ;
   return $css;
}
add_filter( 'woocommerce_email_styles', 'twstudio_woocommerce_email_styles' );
Update cart without the update button in cart.php

31. July 2018

Goes into woocommerce.php or functions.php

/**
 * Update cart without the update button in cart.php
 */
function twstudio_cart_update_qty_script() {
	if (is_cart()) :
		?>
		<script>
			jQuery('div.woocommerce').on('click', '.qty', function(){
				jQuery("[name='update_cart']").removeAttr('disabled');
			});
			jQuery('div.woocommerce').on('change', '.qty', function(){
				jQuery("[name='update_cart']").trigger("click");
			});

		</script>
	<?php
	endif;
}
add_action( 'wp_footer', 'twstudio_cart_update_qty_script' );
Add TILBEHØR (accessories) to WC Tab on single product page

30. July 2018

/**
 * Add TILBEHØR (accessories) tab to single product page
 */
function twstudio_accessories_tab( $tabs ) {
	$accessories = get_field( 'add_accessories' );
	if ( ! empty( $accessories ) ) {
		$tabs['desc_tab'] = array(
			'title'     => __( 'Tilbehør', 'twstudio_lang' ),
			'priority'  => 12,
			'callback'  => 'twstudio_show_cross_sell_in_single_product'
		);
	}
	return $tabs;
}
add_filter( 'woocommerce_product_tabs', 'twstudio_accessories_tab' );

function twstudio_show_cross_sell_in_single_product(){
	$crosssells = get_post_meta( get_the_ID(), '_crosssell_ids',true);
	$args = array(
		'post_type' => 'product',
		'posts_per_page' => -1,
		'post__in' => $crosssells
	);
	$products = new WP_Query( $args );
	if( $products->have_posts() ) :
		echo '<div class="cross-sells">';
		woocommerce_product_loop_start();
		while ( $products->have_posts() ) : $products->the_post();
			wc_get_template_part( 'content', 'product' );
		endwhile; // end of the loop.
		woocommerce_product_loop_end();
		echo '</div>';
	endif;
	wp_reset_postdata();
}
Add extra space to the breadcrumbs

30. July 2018

Goes into woocommerce.php (or functions.php, but you should have a woocommerce.php if you have woocommerce running on your site)

/**
 * Change the breadcrumb separator
 */
function wcc_change_breadcrumb_delimiter( $defaults ) {
	// Change the breadcrumb delimeter from '/' to '>'
	$defaults['delimiter'] = '&nbsp;&nbsp;&nbsp;/&nbsp;&nbsp;&nbsp;';
	return $defaults;
}
add_filter( 'woocommerce_breadcrumb_defaults', 'wcc_change_breadcrumb_delimiter' );

 

Check if a product is in stock

27. July 2018

<?php if ( $product->is_in_stock() ) {
	echo 'Lagerstatus:&nbsp;';
	echo '<img src="';
	echo get_stylesheet_directory_uri();
	echo '/assets/images/pa_lager.png">';
	echo 'På lager';
} else {
	echo 'Lagerstatus:&nbsp;' . 'Bestillingsvare';
}
?>

 

Change sorting

2. July 2018

Change sorting on products that are ‘connected’ to a product

Goes into the functions.php

/**
 * Modify the main query - products sorting on product category pages.
 */
function twstudio_modify_the_main_query( $query ) {
	if ( ! is_admin() && is_product_category() && $query->is_main_query() ) {

		$query->set( 'meta_key', '_sku' );
		$query->set( 'orderby', 'meta_value' );
		$query->set( 'order', 'ASC' );
	}
}
add_action( 'pre_get_posts', 'twstudio_modify_the_main_query' );

Change the orderby and order, to change order.

If you just going to change Standart sorting on all Products. Go to: WooCommerce -> Settings -> Products -> Display -> Default Product Sorting

Add Length, Height and Width to Single-product

16. May 2018

Goes into functions.php

function twstudio_custom_dimension_action() {

	global $product;

	if ( ! empty( $product->get_length() ) ) {

		echo '<div class="dimensions">';
		echo '<br><b>Lengde: </b>' . $product->get_length() . get_option( 'woocommerce_dimension_unit' );
		echo '<br><b>Bredde: </b>' . $product->get_width() . get_option( 'woocommerce_dimension_unit' );
		echo '<br><b>Høyde: </b>' . $product->get_height() . get_option( 'woocommerce_dimension_unit' );
		echo '</div>';
	}

};
add_action( 'woocommerce_single_product_summary', 'twstudio_custom_dimension_action', 55 );
Edit text in WooCommerce Message Error

20. April 2018

add_filter( 'woocommerce_add_error', 'twstudio_change_terms_popup_text' );
function twstudio_change_terms_popup_text( $error ) {
    if( 'You must accept our Terms &amp; Conditions.' == $error ) {
        $error = 'Please accept our terms and conditions to proceed.';
    }
    return $error;
}
Search fix. Hide hidden products when searching.

20. April 2018

add_action( 'pre_get_posts', 'search_query_fix' );
function search_query_fix( $query = false ) {
    if(!is_admin() && is_search()){
        $query->set( 'tax_query', array(
            array(
                'taxonomy' => 'product_visibility',
                'field'    => 'name',
                'terms'    => 'exclude-from-search',
                'operator' => 'NOT IN',
            )
        ));
    }
}