woocommerce product attributes empty - php

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

Related

WooCommerce PHP: Display data from custom meta created in functions.php

I recently created a custom field in functions.php to display a custom meta field in the Inventory tab for each product called barcode. What I now want to do is display the data onto my single product template using a PHP call. Here's first of all, the function to create the barcode data (which works):
function add_barcode(){
woocommerce_wp_text_input(
array(
'id' => '_barcode',
'label' => __( 'Barcode', 'your-plugin' ),
'placeholder' => 'Scan Barcode',
'desc_tip' => 'true',
'description' => __( "Scan the product's barcode.", "your-plugin" )
)
);
}
add_action('woocommerce_product_options_inventory_product_data','add_barcode');
function add_barcode_save( $product ){
if( isset( $_POST['_barcode'] ) ) {
$product->update_meta_data( '_barcode', sanitize_text_field( $_POST['_barcode'] ) );
} else {
$product->delete_meta_data( '_barcode' );
}
}
add_action( 'woocommerce_admin_process_product_object', 'add_barcode_save' );
Here's the PHP I'm trying to generate that data onto the page:
$product = wc_get_product();
echo '<strong>Barcode: </strong>' .$product->get_attribute( 'barcode' );
All I get here is a blank area after the HTML portion. So what function will allow me to display the barcode text?

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!

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.

Make Woocommerce custom checkout field not editable

I added a custom field on the woocommerce checkout page that is populated by URL but I am struggling to find a way to make this field not editable.
I added the following code to function.php:
//Add custom field
function custom_woocommerce_checkout_fields( $checkout_fields = array() ) {
$checkout_fields['order']['imei'] = array(
'type' => 'text',
'class' => array('my-field-class form-row-wide'),
'label' => __('IMEI'),
'placeholder' => __('imei'),
'default' => $_GET['imei'],
);
return $checkout_fields;
}
add_filter( 'woocommerce_checkout_fields', 'custom_woocommerce_checkout_fields' );
What should I change in my code to accomplish this ?
Try this code. It work for me. Just need to add custom attribute parameter to the fields array.
//Display custom field
function custom_woocommerce_checkout_fields( $checkout_fields = array() ) {
$checkout_fields['order']['imei'] = array(
'type' => 'text',
'class' => array('my-field-class form-row-wide'),
'label' => __('IMEI'),
'placeholder' => __('imei'),
'default' => $_GET['imei'],
'custom_attributes' => array( 'disabled' => true)
);
return $checkout_fields;
}
add_filter( 'woocommerce_checkout_fields', 'custom_woocommerce_checkout_fields' );
// Save custom field
add_action( 'woocommerce_checkout_update_order_meta', 'custom_checkout_field_update_order_meta' );
function custom_checkout_field_update_order_meta( $order_id ) {
if ( ! empty( $_POST['imei'] ) ) {
update_post_meta( $order_id, '_imei', sanitize_text_field( $_POST['imei'] ) );
}
}
You should try this text <imput> field with the readonly property (meaning not editable).
You should need to have your 'emei' set in the checkout url like:
http://www.example.com/checkout/?imei=3545454653 to make the field appear with the value as I have this condition: if( empty($_GET['imei'])) return;set in the function.
The code:
// Display
add_action( 'woocommerce_after_order_notes', 'custom_woocommerce_checkout_fields' );
function custom_woocommerce_checkout_fields( $checkout ) {
// Only display field if the 'emei' is set in the checkout url
if( empty($_GET['imei'])) return;
echo '<p class="form-row my-field-class form-row-wide woocommerce-validated" id="imei_field">
<label for="imei" class="">'.__('IMEI').'</label>
<input type="text" class="input-text " name="imei" id="imei" placeholder="'.__('IMEI').'" value="'.$_GET['imei'].'" readonly>
</p>';
}
// Save
add_action( 'woocommerce_checkout_update_order_meta', 'custom_checkout_field_update_order_meta' );
function custom_checkout_field_update_order_meta( $order_id ) {
if ( ! empty( $_POST['imei'] ) ) {
update_post_meta( $order_id, '_imei', sanitize_text_field( $_POST['imei'] ) );
}
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
Tested and work on WooCommerce versions 3+
To get the value (for a defined $order_id):
$imei = get_post_meta( $order_id, '_imei', true );

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