WooComerce, if custom checkbox is checked hide stock status - php

I have a bit trouble with woocomerce checkbox, i add custom checkbox to product page wit this code:
woocommerce_wp_checkbox(
array(
'id' => '_checkbox',
'wrapper_class' => 'show_if_simple',
'label' => __('My Checkbox Field', 'woocommerce' ),
'description' => __( 'Check me!', 'woocommerce' )
)
);
}
then save value with this:
$woocommerce_checkbox = isset( $_POST['_checkbox'] ) ? 'yes' : 'no';
update_post_meta( $post_id, '_checkbox', $woocommerce_checkbox );
Now i tried to write function which make my stock status hiden when this checkbox is checked but i fail , can i ask you guys for some support ?

If the code for saving the option of checkbox works fine and the saved option for that products reflects in the database then adding the following code will help to to complete your task
add_filter('woocommerce_stock_html','wdm_remove_stock_html',10,3);
function wdm_remove_stock_html($availability_html, $availability, $product)
{
if ( 'yes' === get_post_meta( $product->id,'_checkbox', true) ) {
return '';
}else{
return $availability_html;
}
}

Related

woocommerce product attributes empty

I am having problems understanding the following:
I created a custom field in the woocommerce products by the code below.
The custome field shows up and I can fill it as expected.
I don't know how to access the data though.
if I call $product->get_attributes() it returns an empty array.
when I echo $product though I get an json like return value where all expected values are presented.
But how do I access them?
Thanks in advance
function
woocom_general_product_data_custom_field() {
// Create a custom text field
// Textarea
woocommerce_wp_textarea_input(
array(
'id' => '_textarea',
'label' => __( 'textarea' ),
'placeholder' => '',
'description' => __( '',
'woocommerce' )
)
);
}
add_action(
'woocommerce_process_product_meta',
'woocom_save_general_proddata_custom_field' );
function woocom_save_general_proddata_custom_field( $post_id ) {
// Save Textarea
$textarea = $_POST['_textarea'];
if( ! empty( $textarea ) ) {
update_post_meta( $post_id, '_textarea', esc_html( $textarea ) );
}
}
got it now.
I found the info in
$product->get_meta('_textarea');
not in the attributes

Setting a default value for a Woocommerce product field to all products

I created a custom field for my products using this tutorial, but I need to set a default value for this field.
I have already created hundreds of products and I need to have this field updated at those as well. I'm then using this value to order the products.
Here is the whole code:
// Display Fields
add_action('woocommerce_product_options_general_product_data', 'woocommerce_product_custom_fields');
// Save Fields
add_action('woocommerce_process_product_meta', 'woocommerce_product_custom_fields_save');
function woocommerce_product_custom_fields()
{
global $woocommerce, $post;
echo '<div class="product_custom_field">';
// Custom Product Text Field
woocommerce_wp_text_input(
array(
'id' => 'priority',
'placeholder' => 'Priority of the product - values a>b',
'label' => __('Priority of the product', 'woocommerce'),
'desc_tip' => 'true',
//'default' => '0',
)
);
echo '</div>';
}
function woocommerce_product_custom_fields_save($post_id)
{
// Custom Product Text Field
$woocommerce_custom_product_text_field = $_POST['priority'];
if (!empty($woocommerce_custom_product_text_field))
update_post_meta($post_id, 'priority', esc_attr($woocommerce_custom_product_text_field));
}
function cw_add_postmeta_ordering_args( $args_sort_cw ) {
$cw_orderby_value = isset( $_GET['orderby'] ) ? wc_clean( $_GET['orderby'] ) :
apply_filters( 'woocommerce_default_catalog_orderby', get_option( 'woocommerce_default_catalog_orderby' ) );
switch( $cw_orderby_value ) {
case 'priority':
$args_sort_cw['orderby'] = 'meta_value';
$args_sort_cw['order'] = 'asc';
$args_sort_cw['meta_key'] = 'priority';
break;
}
return $args_sort_cw;
}
add_filter( 'woocommerce_get_catalog_ordering_args', 'cw_add_postmeta_ordering_args' );
function cw_add_new_postmeta_orderby( $sortby ) {
$sortby['priority'] = __( 'Recommended', 'woocommerce' );
return $sortby;
}
add_filter( 'woocommerce_default_catalog_orderby_options', 'cw_add_new_postmeta_orderby' );
add_filter( 'woocommerce_catalog_orderby', 'cw_add_new_postmeta_orderby' );
I could't find a working solution, so I'm kindly asking you for an advice. What I expect is that every existing product will have this value set and when creating a new one the default value will be displayed. Then it should be sorted according to this value. Thanks for your help!
Edit according to the first answer:
The data does't update in the database. In the front-end I can only see the products I have manually altered and not those to which the 0 was added using this function. When I try to change the altered value back to 0, it is not updated. Actually I just need a function which would refresh all the products so that the value is stored to the database.
What I would do is use the value argument in the woocommerce_wp_text_input parameters. You can then pass it the current value OR a default if nothing exists yet.
Also added new save routine via woocommerce_admin_process_product_object
// Display Fields
add_action('woocommerce_product_options_general_product_data', 'so_63588126_product_custom_fields');
// Save Fields
add_action('woocommerce_admin_process_product_object', 'so_63588126_product_custom_fields_save');
function so_63588126_product_custom_fields()
{
global $product_object;
$value = $product_object->get_meta( 'weight', true );
if ( ! $value ) {
$value = 0;
}
echo '<div class="product_custom_field">';
// Custom Product Text Field
woocommerce_wp_text_input(
array(
'id' => 'weight',
'placeholder' => 'Weight of the product - values a>b',
'label' => __('Weight of the product', 'your-textdomain'),
'desc_tip' => 'true',
'value' => $value
)
);
echo '</div>';
}
function so_63588126_product_custom_fields_save( $product )
{
// Custom Product Text Field
$woocommerce_custom_product_text_field = $_POST['weight'];
if ( ! empty( $_POST['weight'] ) ) {
$product->update_meta_data( 'weight', sanitize_text_field( wp_unslash( $_POST['weight'] ) ) );
} else {
$product->update_meta_data( 'weight', 0 );
}
}
Additional explanation:
I used $product_object->update_meta_data() as WooCommerce (since 3.0) prefers to use CRUD (create, read, update, delete) methods on objects. update_post_meta() does still work, but CRUD will be future-proof if/when Woo ever decides to use custom tables for products and product meta.
Read more about CRUD: https://docs.woocommerce.com/document/developing-using-woocommerce-crud-objects/
And regarding text domains... This is custom code so in order for it to be properly translated you would need to use your own unique text domain that is not 'woocommerce'.
Read more about text domains: https://developer.wordpress.org/themes/functionality/internationalization/#text-domain
Finally, sanitize_text_field() may not be the right choice for sanitizing, but I didn't know what kind of data you were storing there. intval() would be better for numbers... and so would setting the input to be a numerical input type by setting the type parameter to 'number' in the woocommerce_wp_text_input() args.
This is the solution which worked for me.
// Display Fields
add_action('woocommerce_product_options_general_product_data', 'woocommerce_product_custom_fields');
// Save Fields
add_action('woocommerce_process_product_meta', 'woocommerce_product_custom_fields_save');
function woocommerce_product_custom_fields()
{
global $woocommerce, $post, $product_object;
$value = $product_object->get_meta( 'priority', true );
if ( ! $value ) {
$value = 0;
}
echo '<div class="product_custom_field">';
// Custom Product Text Field
woocommerce_wp_text_input(
array(
'id' => 'priority',
'placeholder' => 'Priority - number 1>0',
'label' => __('Priority', 'woocommerce'),
'type' => 'number',
'desc_tip' => 'true',
'value' => $value
)
);
echo '</div>';
}
function woocommerce_product_custom_fields_save($post_id)
{
// Custom Product Text Field
if (array_key_exists('priority', $_POST)) {
update_post_meta($post_id, 'priority', intval($_POST['priority']));
}
}
function cw_add_postmeta_ordering_args( $args_sort_cw ) {
$cw_orderby_value = isset( $_GET['orderby'] ) ? wc_clean( $_GET['orderby'] ) :
apply_filters( 'woocommerce_default_catalog_orderby', get_option( 'woocommerce_default_catalog_orderby' ) );
switch( $cw_orderby_value ) {
case 'priority':
$args_sort_cw['orderby'] = 'meta_value';
$args_sort_cw['order'] = 'desc';
$args_sort_cw['meta_key'] = 'priority';
break;
}
return $args_sort_cw;
}
add_filter( 'woocommerce_get_catalog_ordering_args', 'cw_add_postmeta_ordering_args' );
function cw_add_new_postmeta_orderby( $sortby ) {
$sortby['priority'] = __( 'Recommended', 'woocommerce' );
return $sortby;
}
add_filter( 'woocommerce_default_catalog_orderby_options', 'cw_add_new_postmeta_orderby' );
add_filter( 'woocommerce_catalog_orderby', 'cw_add_new_postmeta_orderby' );
I adjusted the woocommerce_product_custom_fields_save() function with array_key_exists() and it works fine now.
Thanks helgatheviking for help!

Sync newsletter custom checkbox between checkout and my account in WooCommerce

I would like to synhcronize a custom checkbox field in WooCommerce checkout page with a similar one in the My Account page (when the user is logged in).
Here's my code:
// Show a checkbox in checkout page and in My account > Details
add_action( 'woocommerce_edit_account_form', 'display_checkbox_in_account_page' );
add_action( 'woocommerce_after_order_notes', 'display_checkbox_in_account_page' );
function display_checkbox_in_account_page() {
woocommerce_form_field( 'newsletter-account', array(
'type' => 'checkbox',
'class' => array('form-row-wide'),
'label' => __( 'Subscribe to my newsletter', 'woocommerce' ),
), get_user_meta(get_current_user_id(), 'newsletter-account', true ) );
}
// Save checkbox value when saved in My account > Details
add_action( 'woocommerce_save_account_details', 'save_checkbox_value_from_account_details', 10, 1 );
function save_checkbox_value_from_account_details( $user_id ) {
$value = isset( $_POST['newsletter-account'] ) ? '1' : '0';
update_user_meta( $user_id, 'newsletter-account', $value );
}
Those two blocks of code work fine: if in My account > Details I checked the checkbox, the preference is saved and I can see a checked checkbox also in the checkout page.
Now the problem is that I need a way to obtain the same result when I edit my newsletter preference from the checkout page. I think I need to use the woocommerce_checkout_create_order but I haven't any idea on how to code this:
//Save the checkbox value when customer edit it from the checkout page
add_action( 'woocommerce_checkout_create_order', 'save_checkbox_value_from_checkout_page'. 10, 1 );
function save_checkbox_value_from_checkout_page() {
//some code here
}
Any suggestions are appreciated.
Updated
The hook woocommerce_checkout_create_order is for order meta data and what you need is to save/update your checkout newsletter-account field value as user meta data…
So is better to use dedicated woocommerce_checkout_update_customer hook.
Here is your complete code (tested and working):
add_action( 'woocommerce_edit_account_form', 'display_checkbox_in_account_page' );
add_action( 'woocommerce_after_order_notes', 'display_checkbox_in_account_page' );
function display_checkbox_in_account_page() {
woocommerce_form_field( 'newsletter-account', array(
'type' => 'checkbox',
'class' => array('form-row-wide'),
'label' => __( 'Subscribe to my newsletter', 'woocommerce' ),
), get_user_meta( get_current_user_id(), 'newsletter-account', true ) );
}
// Save/update checkbox value when saved in My account > Details
add_action( 'woocommerce_save_account_details', 'save_checkbox_value_from_account_details', 10, 1 );
function save_checkbox_value_from_account_details( $user_id ) {
$value = isset( $_POST['newsletter-account'] ) ? '1' : '0';
update_user_meta( $user_id, 'newsletter-account', $value );
}
// Save/update custom checkout field value as user meta data
add_action('woocommerce_checkout_update_customer','custom_checkout_checkbox_update_customer', 100, 2 );
function custom_checkout_checkbox_update_customer( $customer, $data ){
$value = isset( $_POST['newsletter-account'] ) ? '1' : '0';
update_user_meta( $customer->get_id(), 'newsletter-account', $value ); // Updated
}
Code goes in functions.php file of your active child theme (or active theme).
Now if you want to grab that information additionally to the order as order meta data you will use:
add_action('woocommerce_checkout_create_order','custom_checkout_checkbox_add_order_meta', 100, 2 );
function custom_checkout_checkbox_add_order_meta( $order, $data ){
$value = isset( $_POST['newsletter-account'] ) ? '1' : '0';
$order->update_meta_data( 'newsletter-account', $value );
}

Show one WooCommerce Product meta

I am using one plugin for WooCommerce GST implementation. It has one HSN field inside product page which is stored in the database as the product meta.
The plugin does not have any specific code to get the HSN value and use it anywhere.
The code for HSN in the plugin is below:
public function fn_add_product_custom_meta_box() {
woocommerce_wp_text_input(
array(
'id' => 'hsn_prod_id',
'label' => __('HSN Code', 'woocommerce' ),
'description' => __( 'HSN Code is mandatory for GST.', 'woocommerce' ),
'custom_attributes' => array( 'required' => 'required' ),
'value' => get_post_meta( get_the_ID(), 'hsn_prod_id', true )
)
);
}
public function fn_save_license_field( $post_id ) {
$value = ( $_POST['hsn_prod_id'] )? sanitize_text_field( $_POST['hsn_prod_id'] ) : '' ;
update_post_meta( $post_id, 'hsn_prod_id', $value );
}
I want to get the HSN value by importing it from product meta and I have used this code to get that without any result:
<?php $meta = get_post_meta( get_the_ID(), 'hsn_prod_id', true ); ?>
Can anyone please check my code and correct me how to add the HSN value anywhere using the code?
I am using the code inside a different plugin to get the HSN code.
Thank you.

Woocommerce coupons adding custom checkbox

I've gotten far enough on this simple function in functions.php that let's me add a checkbox to coupons. However, once I save/update a coupon, my checkbox value (check/unchecked) doesn't get committed (so the checkbox is always unchecked). In other words, I can't get it to update the value to yes in the meta_value column in postmetas when I update/save. The checkbox is there, I just can't use it... highly frustrating! Any sugestions on what I'm doing wrong, please :)
function add_coupon_revenue_dropdown_checkbox() {
$post_id = $_GET['post'];
woocommerce_wp_checkbox( array( 'id' => 'include_stats', 'label' => __( 'Coupon check list', 'woocommerce' ), 'description' => sprintf( __( 'Includes the coupon in coupon check drop-down list', 'woocommerce' ) ) ) );
$include_stats = isset( $_POST['include_stats'] ) ? 'yes' : 'no';
update_post_meta( $post_id, 'include_stats', $include_stats );
do_action( 'woocommerce_coupon_options_save', $post_id );
}add_action( 'woocommerce_coupon_options', 'add_coupon_revenue_dropdown_checkbox', 10, 0 );
The part I'm trying to affect is:
wp-content/plugins/woocommerce/includes/admin/meta-boxes/class-wc-meta-box-coupon-data.php
The problem with your code is that you are attempting to save the value of the checkbox in the same function where you generate the html for it. This won't work. You need to break your current function into two parts that run on two different WooCommerce hooks.
The first is to display the actual checkbox:
function add_coupon_revenue_dropdown_checkbox() {
woocommerce_wp_checkbox( array( 'id' => 'include_stats', 'label' => __( 'Coupon check list', 'woocommerce' ), 'description' => sprintf( __( 'Includes the coupon in coupon check drop-down list', 'woocommerce' ) ) ) );
}
add_action( 'woocommerce_coupon_options', 'add_coupon_revenue_dropdown_checkbox', 10, 0 );
The second is to save the value of the checkbox when the submitted form is being processed.
function save_coupon_revenue_dropdown_checkbox( $post_id ) {
$include_stats = isset( $_POST['include_stats'] ) ? 'yes' : 'no';
update_post_meta( $post_id, 'include_stats', $include_stats );
}
add_action( 'woocommerce_coupon_options_save', 'save_coupon_revenue_dropdown_checkbox');

Categories