Enable metabox on only shop orders with ACF - woocommerce

I am trying to enable the metabox only for shop_orders, as ACF disables them. I am aware of the general filter add_filter('acf/settings/remove_wp_meta_box', '__return_true');, but I want to limit this only to shop orders, as there are essential fields for us. But I do not want to enable it throughout all post types.
I struggle to call the condition for shop_order. It's not finding the if statement:
add_action( 'admin_init', 'enable_metabox' );
function enable_metabox(){
if( get_post_type() === 'shop_order' ){
acf_update_setting('remove_wp_meta_box', false);
}
}
I have tried with $post_id, no luck.

Related

Automatically Update Order Status to Complete When Shipment Tracking Number Input - WooCommerce

I'm trying to figure out the best way to automatically update the order status in WooCommerce when the tracking information is inputted via the official WooCommerce Shipment Tracking plugin. I found the doc from Woo on how to automatically complete orders, but I only want this to execute when the tracking number is added. Any help would be greatly appreciated!
Below is the code from Woo:
/**
* Auto Complete all WooCommerce orders.
*/
add_action( 'woocommerce_thankyou', 'custom_woocommerce_auto_complete_order' );
function custom_woocommerce_auto_complete_order( $order_id ) {
if ( ! $order_id ) {
return;
}
$order = wc_get_order( $order_id );
$order->update_status( 'completed' );
}
And here are the meta references from the plugin:
The Shipping Tracking plugin stores the tracking information in the order meta with the meta key _wc_shipment_tracking_items. It’s an array with the following structure:
tracking_provider — String of predefined provider
custom_tracking_provider — String of custom provider
custom_tracking_link — String of custom tracking URL tracking_number
String of tracking number date_shipped — Timestamp of shipment date
As you said you are using the "WooCommerce Shipment Tracking plugin." but in that plugin, I didn't find any filters or hooks that will help to update status when the tracking number is added. but I found that they use update_post_meta() to update the tracking code so you can use the update_postmeta action hook to update order status.
Try the below code. code will go in your active theme functions.php file.
function update_order_status_when_shipment_tracking_input( $meta_id, $object_id, $meta_key, $meta_value ){
if( $meta_key == '_wc_shipment_tracking_items' ){
error_log('update_order_status_when_shipment_tracking_input');
$order = wc_get_order( $object_id );
if( $order ){
$order->update_status( 'completed' );
}
}
}
add_action( 'update_postmeta', 'update_order_status_when_shipment_tracking_input', 10, 4 );

Woocommerce skip checkout for free products

I'm building webpage on WP and Woocommerce - I would like to skip cart and also checkout page for free products (or products which ID-s I can specify). These products are free and virtual (no payment needed, no shipping needed). The webpage is only used by registered users - so all the customer info is present.
The result I would like to have is that if you press ORDER button on product page - the order is done and customer is redirected to Thank-You page.
BR,
Kaspar
I applied the same concept, but found a major issue when processing order on the checkout; fields were still required.
The primary issue was processing the order via AJAX ( was using is_ajax() ), and even though it was on the checkout page, it wasn't returning as true. It's possible there was a recent change, or it could be the site's environment (theme).
Here are some of the conditional tags: https://docs.woocommerce.com/document/conditional-tags/
Seeing how things change, the answer can be edited here, but the original concept is located at: https://www.skyverge.com/blog/how-to-simplify-free-woocommerce-checkout/
function wc_free_checkout_fields() {
// Bail we're not at checkout, or if we're at checkout OR AJAX (payment process) but payment is needed.
if ( function_exists( 'is_checkout' ) && ( ! ( is_checkout() || is_ajax() ) || ( ( is_checkout() || is_ajax() ) && WC()->cart->needs_payment() ) ) ) {
return;
}
// Remove coupon forms since it's irrelevant with a free cart?
remove_action( 'woocommerce_before_checkout_form', 'woocommerce_checkout_coupon_form', 10 );
// Remove the "Additional Info" order notes.
add_filter( 'woocommerce_enable_order_notes_field', '__return_false' );
// Unset the fields we don't want in a free checkout.
function wc_unset_unwanted_checkout_fields( $fields ) {
// Add or remove billing fields you do not want.
// #link http://docs.woothemes.com/document/tutorial-customising-checkout-fields-using-actions-and-filters/#section-2
$billing_keys = array(
'billing_company',
'billing_phone',
'billing_address_1',
'billing_address_2',
'billing_city',
'billing_postcode',
'billing_country',
'billing_state',
);
// For each unwanted billing key, unset.
foreach( $billing_keys as $key ) {
unset( $fields['billing'][$key] );
}
return $fields;
}
add_filter( 'woocommerce_checkout_fields', 'wc_unset_unwanted_checkout_fields' );
// A tiny CSS tweak for the account fields; this is optional.
function wc_print_custom_css() {
?>
<style>
.create-account {
margin-top: 6em;
}
</style>
<?php
}
add_action( 'wp_head', 'wc_print_custom_css' );
}
add_action( 'wp', 'wc_free_checkout_fields' );
Check if the checkout has no cost with the WC()->cart->needs_payment() check.
see this for more info:
https://www.skyverge.com/blog/how-to-simplify-free-woocommerce-checkout/

Hiding prices in WooCommerce for a set of products

In our Woocommerce products, we have two types of products.
Products imported through script from a external XML url file.
Products added as usual through woo admin interface.
We have added a meta field to identify these imported products.
What is the best method to hide prices ONLY for these imported products?
I have tried by removing some woocommerce actions, but its affects all woo products.
I have tried by removing some woocommerce actions, but its affects all woo products.
Then you need conditional logic. This should get rid of the price display in the loop.
EDIT As pointed out in the comments, once you remove the action it is permanently removed for all ensuing products. So in light of that I have added an else statement that resolves this issue.
function so_32584641_remove_price_from_loop(){
global $product;
if( 'mycbgenie' == get_post_meta( $product->id, '_mycbgenie_managed_by', true ) ){
remove_action( 'woocommerce_after_shop_loop_item_title', 'woocommerce_template_loop_price' );
} else {
add_action( 'woocommerce_after_shop_loop_item_title', 'woocommerce_template_loop_price' );
}
}
add_action( 'woocommerce_before_shop_loop_item', 'so_32584641_remove_price_from_loop' );
and this should remove it from the single product page:
function so_32584641_remove_price_from_single(){
global $product;
$your_meta = get_post_meta( $product->id, '_your_meta_key', true );
if( 'mycbgenie' == $your_meta ){
remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_price' );
}
}
add_action( 'woocommerce_before_single_product', 'so_32584641_remove_price_from_single' );

How is clicking 'update' on a post different from programatically creating posts?

hoping for some advice.
I'm programmatically inserting a large number of posts into wordpress from a JSON feed. The wp_insert_post function is working brilliantly and the posts are created, along with correctly populated Advanced Custom Fields meta data.
We have a strange issue by which until we manually click "update" on a single post the custom fields aren't available using a JSON API plugin.
I've tried updating all via the bulk editor, as well as calling wp_update_post after the JSON import. It's as if the act of clicking "update" on a single post saves the post in a different fashion.
Can anyone advise why this would be the case? Any advice or pointing in the right direction would be greatly appreciated!
EDIT: the code we're using to update our post meta...
function __update_post_meta( $post_id, $field_name, $value = '' ) {
if ( empty( $value ) OR ! $value )
{
delete_post_meta( $post_id, $field_name );
}
elseif ( ! get_post_meta( $post_id, $field_name ) )
{
add_post_meta( $post_id, $field_name, $value );
}
else
{
update_post_meta( $post_id, $field_name, $value );
}
}
So we resolved the particular issue we were having.
When a post is programmatically created with ACF fields, the posts are not labelled in the same way as standard post meta. Read here for more info on that!
Updating a post manually creates the necessary "aliases". Until that point, if you want to get the info out, you need to reference ACF's initial "fieldXXXXXXXX" post meta key.

Prevent WooCommerce brand from being sellable

Hi there we have an online store running on WooCommerce and using the WooCommerce brands plugin (http://docs.woothemes.com/document/wc-brands/) but there is one brand that we are allowed show online with price but not allowed to actually sell.
Is there a function I can add for this particular brand to functions.php that will change the add to cart button in category or widget layout to "more info" and link to the product and then on the product page instead of the add to cart section just have a text message saying to call the store.
You can filter WooCommerce's is_purchasable method. Any item that returns false will not be able to be purchased.
function so_26378581_purchasable( $purchasable, $product ){
if ( has_term( 'your-brand', 'product_brand', $product->id ) ){
$purchasable = false;
}
return $purchasable;
}
add_action( 'woocommerce_is_purchasable', 'so_26378581_purchasable', 10, 2 );
This uses conditional logic to test whether the $product in question has the your-brand term in the product_brand taxonomy... via the has_term() function.
By the way, this is not the type of functionality that belongs in functions.php. Your theme should only be concerned with display/appearances. I would recommend that you make this its own plugin, or add to to a site specific snippets plugin.
to me it made no error message, but it did not work, as applied in my test subject and stand continues with two products of different brands.
I put this code:
function so_26378581_purchasable( $purchasable, $product ){
if ( has_term( 'product_brand', 'product_brand', $product->id ) ){
$purchasable = false;
}
return $purchasable;
}
add_action( 'woocommerce_is_purchasable', 'so_26378581_purchasable', 10, 2 );

Resources