I am trying to hide product attributes in woocommerce based on product title. currently I have code that removes the attributed based on category. It works fine for what it is, but I would prefer to use title and a strpos array instead.
Here is the code that allows me to remove attributes based on categories
add_action( 'wp', 'remove_product_content11' );
function remove_product_content11() {
if ( has_term( array('Flush Mount', 'Semi Flush'), 'product_cat' ) ) {
function mycode_hide_attributes_from_additional_info_tabs( $attributes, $product ) {
$hidden_attributes = [
'pa_item-length-or-depth',
'pa_item-minimum-height',
];
foreach ( $hidden_attributes as $hidden_attribute ) {
if ( ! isset( $attributes[ $hidden_attribute ] ) ) {
continue;
}
$attribute = $attributes[ $hidden_attribute ];
$attribute->set_visible( false );
}
return $attributes;
}
add_filter( 'woocommerce_product_get_attributes', 'mycode_hide_attributes_from_additional_info_tabs', 20, 2 );
}
}
I would just like to change this code so It uses strpos to search though the product title, instead of using category.
check this code, tell me if it helps.
add_action( 'wp', 'remove_product_content11' );
function remove_product_by_strpos_title() {
global $post;
// check if its a product page, so the code is not executed for every page
// and check if title contains 'my-title'
if ( is_product() && strpos('my-title', $post->post_title) ) {
function mycode_hide_attributes_from_additional_info_tabs( $attributes, $product ) {
$hidden_attributes = [
'pa_item-length-or-depth',
'pa_item-minimum-height',
];
foreach ( $hidden_attributes as $hidden_attribute ) {
if ( ! isset( $attributes[ $hidden_attribute ] ) ) {
continue;
}
$attribute = $attributes[ $hidden_attribute ];
$attribute->set_visible( false );
}
return $attributes;
}
add_filter( 'woocommerce_product_get_attributes', 'mycode_hide_attributes_from_additional_info_tabs', 20, 2 );
}
}
Related
I'm looking for a way to highlight the admin order list line based on the order shipping method. (specifically for local pickup)
Based on Highlight WooCommerce admin orders list based on order payment method
anwser code, I have changed $payment_method for $shipping_method and .type-shop_order.cod for .type-shop_order.local_pickupcode for shipping methods but it did nothing in admin panel
I have also tried using shipping method title instead of $shipping_method, but it did nothing.
i have also tried to get all classes with
public function get_shipping_classes() {
if ( empty( $this->shipping_classes ) ) {
$classes = get_terms(
'product_shipping_class',
array(
'hide_empty' => '0',
'orderby' => 'name',
)
);
$this->shipping_classes = ! is_wp_error( $classes ) ? $classes : array();
}
return apply_filters( 'woocommerce_get_shipping_classes', $this->shipping_classes );
}
but it hid all orders except local pickup.
Here is the code:
function filter_post_class( $classes, $class, $post_id ) {
// Determines whether the current request is for an administrative interface page
if ( ! is_admin() ) return $classes;
// Get the current screen object
$current_screen = get_current_screen();
// Only when
if ( $current_screen->id === 'edit-shop_order' ) {
// Get an instance of the WC_Order object
$order = wc_get_order( $post_id );
// Is a WC_Order
if ( is_a( $order, 'WC_Order' ) ) {
// Get the payment method
$shipping_method = $order->get_shipping_method();
//NOT empty
if ( ! empty( $shipping_method ) ) {
$classes[] = $shipping_method;
}
}
}
// Return the array
return $classes;
}
add_filter( 'post_class', 'filter_post_class', 10, 3 );
// Add CSS
function action_admin_head() {
// Get the current screen object
$current_screen = get_current_screen();
// Only when
if ( $current_screen->id === 'edit-shop_order' ) {
echo '<style>
.type-shop_order.local_pickup {
background-color: #e9a5a5 !important;
}
</style>';
}
}
add_action( 'admin_head', 'action_admin_head' );
Any advice how to change it please? i am not php coder so this is kinda google try thing for me :/
i have made it thanks to CBroe.
function filter_post_class( $classes, $class, $post_id ) {
// Determines whether the current request is for an administrative interface page
if ( ! is_admin() ) return $classes;
// Get the current screen object
$current_screen = get_current_screen();
// Only when
if ( $current_screen->id === 'edit-shop_order' ) {
// Get an instance of the WC_Order object
$order = wc_get_order( $post_id );
// Is a WC_Order
if ( is_a( $order, 'WC_Order' ) ) {
// Get the shipping method
$shipping_method = #array_shift($order->get_shipping_methods());
$shipping_method_id = $shipping_method['method_id'];
//NOT empty
if ( ! empty( $shipping_method ) ) {
$classes[] = $shipping_method_id;
}
}
}
// Return the array
return $classes;
}
add_filter( 'post_class', 'filter_post_class', 10, 3 );
// Add CSS
function action_admin_head() {
// Get the current screen object
$current_screen = get_current_screen();
// Only when
if ( $current_screen->id === 'edit-shop_order' ) {
echo '<style>
.type-shop_order.local_pickup {
background-color: #e9a5a5 !important;
}
</style>';
}
}
add_action( 'admin_head', 'action_admin_head' );
I know how to add a meta on the order shipping method :
$shippingMethodItem->update_meta_data('num_packages', 0);
But I want to add/update this meta automatically when the order is placed OR when someone add/edit order items manually.
I already tried with no result :
add_action( 'woocommerce_checkout_create_order_shipping_item', [$this, 'actionCheckoutCreateOrderShippingItem'] );
...
public function actionCheckoutCreateOrderShippingItem ($shippingMethodItem, $package_key, $package, $order)
{
$shippingMethodItem->update_meta_data( 'num_packages', 0);
$shippingMethodItem->save();
}
The following will add custom specific order "shipping" item meta data on orders via checkout and/or manual admin orders too:
// For new orders via checkout
add_action( 'woocommerce_checkout_create_order_shipping_item', 'action_checkout_create_order_shipping_item', 10, 4 );
function action_checkout_create_order_shipping_item ( $item, $package_key, $package, $order ){
$item->update_meta_data( 'num_packages', 0 );
}
// For manual admin orders
add_action( 'woocommerce_saved_order_items', 'action_saved_order_items_callback', 10, 2 );
function action_saved_order_items_callback( $order_id, $items ) {
if ( isset( $items['shipping_method_id'] ) ) {
foreach( $items['shipping_method_id'] as $item_id ) {
$num_packages = wc_get_order_item_meta($item_id, 'num_packages');
if ( empty($num_packages) || $num_packages != 0 ) {
wc_update_order_item_meta( $item_id, 'num_packages', 0 );
}
}
}
}
Code goes in functions.php file of the active child theme (or active theme). Tested and works.
To use this code in a plugin with a class (OOP), add the following inside the constructor function:
// For checkout order
add_action( 'woocommerce_checkout_create_order_shipping_item', [$this, 'action_checkout_create_order_shipping_item'], 10, 4 );
// For checkout order
add_action( 'woocommerce_saved_order_items', [$this, 'action_saved_order_items_callback'], 10, 2 );
And the following outside the constructor function:
public function action_checkout_create_order_shipping_item ( $item, $package_key, $package, $order ){
$item->update_meta_data( 'num_packages', 0 );
}
public function action_saved_order_items_callback( $order_id, $items ) {
if ( isset( $items['shipping_method_id'] ) ) {
foreach( $items['shipping_method_id'] as $item_id ) {
$num_packages = wc_get_order_item_meta($item_id, 'num_packages');
if ( empty($num_packages) || $num_packages != 0 ) {
wc_update_order_item_meta( $item_id, 'num_packages', 0 );
}
}
}
}
So I have found the way to remove all of that in Posts (for non admins) with the following line:
/**
* Remove the 'all', 'publish', 'future', 'sticky', 'draft', 'pending', 'trash'
* views for non-admins
*/
add_filter( 'views_edit-post', function( $views )
{
if( current_user_can( 'manage_options' ) )
return $views;
$remove_views = [ 'all','publish','future','sticky','draft','pending','trash' ];
foreach( (array) $remove_views as $view )
{
if( isset( $views[$view] ) )
unset( $views[$view] );
}
return $views;
} );
Now I want to remove all of those in Comments as well.
I can't find the answer.
Any help would be appreciated.
As said in the comments, just add another add_filter with "views_edit-comments".
To always show only own comments to a non-admin user, use the follow code:
add_action( 'current_screen', 'wp_66446729_filter_comments', 10, 2 );
function wp_66446729_filter_comments( $screen )
{
if ( current_user_can('administrator') )
return;
add_action( 'pre_get_comments', 'wp_66446729_list_own_comments_only', 10, 1 );
}
function wp_66446729_list_own_comments_only( $clauses )
{
$user_id = get_current_user_id();
if ($user_id) {
$clauses->query_vars['user_id'] = $user_id;
}
}
I successfully created a ACF custom field in WooCommerce within my product variations in the backend. The field is properly shown within each variation.
But after editing this or other fields within the variations I can't save the whole variations tab anymore. The loading/saving indicator circle continues to rotate indefinitely. And the custom field is not showing in the single product variation in frontend.
What I did, was to add the following code to my functions.php:
/* ACF filter for Variations */
// Render fields at the bottom of variations - does not account for field group order or placement.
$GLOBALS['wc_loop_variation_id'] = null;
function is_field_group_for_variation($field_group, $variation_data, $variation_post) {
return (preg_match( '/Variation/i', $field_group['title'] ) == true);
}
add_action( 'woocommerce_product_after_variable_attributes', function( $loop_index, $variation_data, $variation_post ) {
$GLOBALS['wc_loop_variation_id'] = $variation_post->ID;
foreach ( acf_get_field_groups() as $field_group ) {
if ( is_field_group_for_variation( $field_group, $variation_data, $variation_post ) ) {
acf_render_fields( $variation_post->ID, acf_get_fields( $field_group ) );
}
}
$GLOBALS['wc_loop_variation_id'] = null;
}, 10, 3 );
add_action( 'woocommerce_save_product_variation', function( $variation_id, $loop_index ) {
if ( !isset( $_POST['acf_variation'][$variation_id] ) ) {
return;
}
$_POST['acf'] = $_POST['acf_variation'][$variation_id];
acf()->input->save_post( $variation_id );
}, 10, 2 );
add_filter( 'acf/prepare_field', function ( $field ) {
if ( !$GLOBALS['wc_loop_variation_id'] ) {
return $field;
}
$field['name'] = preg_replace( '/^acf\[/', 'acf_variation[' . $GLOBALS['wc_loop_variation_id'] . '][', $field['name'] );
return $field;
}, 10, 1);
//add ACF rule
add_filter('acf/location/rule_values/post_type', 'acf_location_rule_values_Post');
function acf_location_rule_values_Post( $choices ) {
$choices['product_variation'] = 'Product Variation';
//print_r($choices);
return $choices;
}
/* End */
Any help would be appreciated.
acf()->input->save_post( $variation_id );
Should be
do_action( 'acf/save_post', $variation_id );
Credit to onoweb from here https://support.advancedcustomfields.com/forums/topic/acf-on-product-variations-almost-works/
I'm trying to change the WooCommerce price dynamically on WooCommerce, already tried various solution posted here, but no one worked for my case.
Here's an example, I have an ajax function that calls the receive_order_ajax_request function, add the products into the cart, and after I call the update_vehicle_price to update the product's price. But all products remains with the same price. Can someone give me a help?
class WhollOrder {
public function __construct() {
add_action( 'wp_ajax_nopriv_receive_order_ajax_request', array( $this, 'receive_order_ajax_request' ) );
add_action( 'wp_ajax_receive_order_ajax_request', array( $this, 'receive_order_ajax_request' ) );
}
public function receive_order_ajax_request() {
global $woocommerce;
$booking_details = $_POST['booking_details'];
if ( isset( $booking_details ) && ! empty( $booking_details ) ) {
foreach ( $booking_details['vehicles'] as $vehicle ) {
$woocommerce->cart->add_to_cart( $vehicle['product_id'], (int) $vehicle['product_qty'] );
}
$this->update_vehicle_price( $booking_details['vehicles'] );
} else {
wp_send_json_error(
array(
'message' => 'Preencha todos os campos'
)
);
}
wp_die();
}
private function update_vehicle_price( $vehicles ) {
global $woocommerce;
foreach ( WC()->cart->get_cart() as $key => $cart_item ) {
foreach ( $vehicles as $vehicle ) {
if ( $vehicle['product_id'] == $cart_item['product_id'] ) {
WC()->cart->get_cart()[$key]['data']->set_price( 1000.00 );
}
}
}
}
}
new WhollOrder();
This is not a duplicate because the way I coded is not possible to use the others question's answers.
Yea dude, I've been here. The price is reloaded after you go to the checkout page.
You need to set it using this hook : woocommerce_checkout_create_order_line_item.
Change cart item prices in WooCommerce version 3.0