Disable editing specific admin custom fields in Woocommerce - php

I have some custom fields for my Woocommerce products inside my Inventory Tab using woocommerce_wp_text_input() function. I would like to add one more custom text field just for displaying a value for reference.
I want to lock the textfield by default so as not to be able to write something in it.
Is it possible?

Yes it is possible adding the as custom_attributes the readonly property in the field arguments array using:
'custom_attributes' => array('readonly' => 'readonly'),
So your code will be like:
add_action( 'woocommerce_product_options_stock_status', 'display_product_options_inventory_custom_fields', 20 );
function display_product_options_inventory_custom_fields() {
global $post;
echo '</div><div class="options_group">'; // New separated section
// Text field (conditionally readonly)
woocommerce_wp_text_input( array(
'id' => '_text_field_ro',
'type' => 'text',
'label' => __( 'Read only field', 'woocommerce' ),
'placeholder' => __( 'placeholder text', 'woocommerce' ),
'description' => __( 'Custom description: your explanations.', 'woocommerce' ),
'desc_tip' => true,
'custom_attributes' => $readonly, // Enabling read only
) );
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
Update: Adding a checkbox to enable the readonly fields:
add_action( 'woocommerce_product_options_stock_status', 'display_product_options_inventory_custom_fields', 20 );
function display_product_options_inventory_custom_fields() {
global $post;
echo '</div><div class="options_group">'; // New separated section
// Checkbox
woocommerce_wp_checkbox( array(
'id' => '_enable_readonly',
'label' => __( 'Enable readonly fields', 'woocommerce' ),
'description' => __( 'Enable some fields to be readonly', 'woocommerce' ),
'desc_tip' => true,
));
// Get the checkbox value
$checkbox = get_post_meta( $post->ID, '_enable_readonly', true );
// We set the field attribute "readonly" conditionally based on the checkbox
$readonly = empty($checkbox) ? '' : array('readonly' => 'readonly');
// Text field 1 (conditionally readonly)
woocommerce_wp_text_input( array(
'id' => '_text_field_ro1',
'type' => 'text',
'label' => __( 'Read only field 1', 'woocommerce' ),
'placeholder' => __( 'placeholder text 1', 'woocommerce' ),
'description' => __( 'Custom description 1: your explanations.', 'woocommerce' ),
'desc_tip' => true,
'custom_attributes' => $readonly, // Enabling read only
) );
// Text field 2 (conditionally readonly)
woocommerce_wp_text_input( array(
'id' => '_text_field_ro2',
'type' => 'text',
'label' => __( 'Read only field 2', 'woocommerce' ),
'placeholder' => __( 'placeholder text 2', 'woocommerce' ),
'description' => __( 'Custom description 2: your explanations.', 'woocommerce' ),
'desc_tip' => true,
'custom_attributes' => $readonly, // Enabling read only
) );
}
add_action( 'woocommerce_process_product_meta', 'save_product_custom_fields' );
function save_product_custom_fields( $post_id ) {
// 1. readonly checkbox
$readonly = isset( $_POST['_enable_readonly'] ) ? esc_attr( $_POST['_enable_readonly'] ) : '';
update_post_meta( $post_id, '_enable_readonly', $readonly );
// 2. Readonly fields: allow saving when readonly is disabled
if( ! isset( $_POST['_enable_readonly'] ) ){
// Save text field 1 value
if( isset( $_POST['_text_field_ro1'] ) ){
update_post_meta( $post_id, '_text_field_ro1', sanitize_text_field( $_POST['_text_field_ro1'] ) );
}
// Save text field 2 value
if( isset( $_POST['_text_field_ro2'] ) ){
update_post_meta( $post_id, '_text_field_ro2', sanitize_text_field( $_POST['_text_field_ro2'] ) );
}
}
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
Checkbox is disabled (fields are not readonly):
Checkbox is enabled (fields are readonly):

Related

Add a field only on admin products from a custom type in WooCommerce

I made custom field in product backend, that I want to be only for Product type pw-gift-card:
function creating_final_sku_field(){
global $product;
if ($product->is_type('pw-gift-card')) {
$args = array(
'label' => __( 'Final SKU', 'woocommerce' ),
'placeholder' => __( 'Enter final SKU here', 'woocommerce' ),
'id' => 'final_sku',
'desc_tip' => true,
'description' => __( 'This SKU is for final use only.', 'woocommerce' ),
);
woocommerce_wp_text_input( $args );
}
}
add_action( 'woocommerce_product_options_sku', 'creating_final_sku_field' );
This is code throws a critical error.
Any help is appreciated.
The main error comes from undefined $product variable. Try the following instead:
add_action( 'woocommerce_product_options_sku', 'add_product_final_sku_custom_field' );
function add_product_final_sku_custom_field(){
global $post, $product_object;
if ( ! is_a( $product_object, 'WC_Product' ) ) {
$product_object = wc_get_product( $post->ID );
}
if ( $product_object->is_type('pw-gift-card') ) {
woocommerce_wp_text_input( array(
'label' => __( 'Final SKU', 'woocommerce' ),
'placeholder' => __( 'Enter final SKU here', 'woocommerce' ),
'id' => 'final_sku',
'desc_tip' => true,
'description' => __( 'This SKU is for final use only.', 'woocommerce' ),
) );
}
}
Code goes in functions.php file of the active child theme (or active theme).
Important Note: Specifying a product type as condition will not work when adding a new product, as the product type is not yet saved. This need to be done some CSS...

Adding custom settings tab for simple products in Woocommerce

I am having a problem trying to add a custom field called Discount_info to a simple product.
I have created a new tab called discount_info which shows up in the simple product view just fine. Problem is trying to add a custom number field to this tab. I'm using the code below which is causing a 500 error. Any ideas where i am going wrong?
// Display Fields using WooCommerce Action Hook
add_action( 'woocommerce_product_options_discount_info',
'woocom_general_product_data_custom_field' );
function woocom_general_product_data_custom_field() {
// Create a custom text field
// Number Field
woocommerce_wp_text_input(
array(
'id' => '_discount_info',
'label' => __( 'Discount %', 'woocommerce' ),
'placeholder' => '',
'description' => __( 'Enter the % discount here.', 'woocommerce' ),
'type' => 'number',
'custom_attributes' => array(
'step' => 'any',
'min' => '1'
)
)
);
}
// Hook to save the data value from the custom fields
add_action( 'woocommerce_process_product_meta',
'woocom_save_general_proddata_custom_field' );
/** Hook callback function to save custom fields information */
function woocom_save_general_proddata_custom_field( $post_id ) {
// Save Number Field
$number_field = $_POST['_discount_info'];
if( ! empty( $number_field ) ) {
update_post_meta( $post_id, '_discount_info', esc_attr( $number_field ) );
}
}
First remove all related code, and try this instead:
// Add a custom product setting tab to edit product pages options FOR SIMPLE PRODUCTS only
add_filter( 'woocommerce_product_data_tabs', 'discount_new_product_data_tab', 50, 1 );
function discount_new_product_data_tab( $tabs ) {
$tabs['discount'] = array(
'label' => __( 'Discount', 'woocommerce' ),
'target' => 'discount_product_data', // <== to be used in the <div> class of the content
'class' => array('show_if_simple'), // or 'hide_if_simple' or 'show_if_variable'…
);
return $tabs;
}
// Add/display custom Fields in the custom product settings tab
add_action( 'woocommerce_product_data_panels', 'add_custom_fields_product_options_discount', 10 );
function add_custom_fields_product_options_discount() {
global $post;
echo '<div id="discount_product_data" class="panel woocommerce_options_panel">'; // <== Here we use the target attribute
woocommerce_wp_text_input( array(
'type' => 'number', // Add an input number Field
'id' => '_discount_info',
'label' => __( 'Percentage Discount', 'woocommerce' ),
'placeholder' => __( 'Enter the % discount.', 'woocommerce' ),
'description' => __( 'Explanations about the field info discount.', 'woocommerce' ),
'desc_tip' => 'true',
'custom_attributes' => array(
'step' => 'any',
'min' => '1'
),
) );
echo '</div>';
}
// Save the data value from the custom fields for simple products
add_action( 'woocommerce_process_product_meta_simple', 'save_custom_fields_product_options_discount', 50, 1 );
function save_custom_fields_product_options_discount( $post_id ) {
// Save Number Field value
$number_field = $_POST['_discount_info'];
if( ! empty( $number_field ) ) {
update_post_meta( $post_id, '_discount_info', esc_attr( $number_field ) );
}
}
Code goes in function.php file of your active child theme (or active theme). Tested and work.
There aren't enough information to help know the exact problem, but it worth testing with a cleaner version of your code:
// Display Fields using WooCommerce Action Hook
add_action( 'woocommerce_product_options_discount_info', 'wc_general_product_data_custom_field' );
function wc_general_product_data_custom_field() {
// Number Field
woocommerce_wp_text_input( array(
'id' => '_discount_info',
'label' => __( 'Discount %', 'woocommerce' ),
'desc_tip' => 'true',
'description' => __( 'Enter the % discount here.', 'woocommerce' ),
'type' => 'number',
'custom_attributes' => array(
'min' => '1',
'step' => '1',
),
) );
}
// Hook to save the data value from the custom fields
add_action( 'woocommerce_process_product_meta', 'wc_save_general_proddata_custom_field' );
/** Hook callback function to save custom fields information */
function wc_save_general_proddata_custom_field( $post_id ) {
// Save Number Field
$number_field = isset( $_POST['_discount_info'] ) ? $_POST['_discount_info'] : '';
if( ! empty( $number_field ) ) {
update_post_meta( $post_id, '_discount_info', $number_field );
}
}

Add custom fields to WooComerce product setting pages in the shipping tab

Is it possible to do add some extra fields in WooCommerce products pages shipping tab settings in backend, as I need to add something like 12 custom fields.
I have tried to find some related hooks without success. The only way that I have found was over attributes, but it was not a convenient solution…
How can I add custom fields to WooComerce product setting pages in the shipping tab?
This is possible and you will get this (here I have set to custom text fields):
Here is the code:
// Add custom fields to product shipping tab
add_action( 'woocommerce_product_options_shipping', 'add_custom_shipping_option_to_products');
function add_custom_shipping_option_to_products(){
global $post, $product;
echo '</div><div class="options_group">'; // New option group
woocommerce_wp_text_input( array(
'id' => '_custom_text_field1',
'label' => __( 'My Text Field one', 'woocommerce' ),
'placeholder' => 'something',
'desc_tip' => 'true',
'description' => __( 'Enter the custom value here.', 'woocommerce' ),
'value' => get_post_meta( $post->ID, '_custom_meta_field1', true ),
) );
woocommerce_wp_text_input( array(
'id' => '_custom_text_field2',
'label' => __( 'My Text Field two', 'woocommerce' ),
'placeholder' => 'something',
'desc_tip' => 'true',
'description' => __( 'Enter the custom value here.', 'woocommerce' ),
'value' => get_post_meta( $post->ID, '_custom_meta_field2', true ),
) );
}
// Save the custom fields values as meta data
add_action( 'woocommerce_process_product_meta', 'save_custom_shipping_option_to_products' );
function save_custom_shipping_option_to_products( $post_id ){
$custom_text_field1 = $_POST['_custom_text_field1'];
if( isset( $custom_text_field1 ) )
update_post_meta( $post_id, '_custom_meta_field1', esc_attr( $custom_text_field1 ) );
$custom_text_field2 = $_POST['_custom_text_field2'];
if( isset( $custom_text_field2 ) )
update_post_meta( $post_id, '_custom_meta_field2', esc_attr( $custom_text_field2 ) );
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
This code is tested on WooCommerce 3+ and works

Retrieving the label name for a custom fields in backend product tabs

Below is the WooCommerce Custom Product with custom field, custom tab and it's content:
I'm sampling the first text field at this tab. Goal is to get the "label" property of these fields.
function launch_product_tab_content() {
global $post;
?><div id='launch_contents' class='panel woocommerce_options_panel'><?php
?><div class='options_group'><?php
woocommerce_wp_text_input( array(
'id' => '_text_announced',
'label' => __( 'Announced(Global)', 'woocommerce' ),
'desc_tip' => 'true',
'description' => __( 'Year and Month it was announced global', 'woocommerce' ),
'type' => 'text',
) );
woocommerce_wp_text_input( array(
'id' => '_text_announced_ph',
'label' => __( 'Announced(Philippines)', 'woocommerce' ),
'desc_tip' => 'true',
'description' => __( 'Year and Month it was announced global', 'woocommerce' ),
'type' => 'text',
) );
woocommerce_wp_text_input( array(
'id' => '_text_availability_ph',
'label' => __( 'Availability(Philippines)', 'woocommerce'),
'desc_tip' => 'true',
'description' => __( 'Schedule date of availability in the Philippines', 'woocommerce' ),
'type' => 'text',
) );
?></div>
</div><?php
}
add_action( 'woocommerce_product_data_panels', 'launch_product_tab_content' );
This is what it looks like at the Product editor page, Custom Product at Wordpress:
Now, using ACF, I used this code:
<?php
$field_key = "_text_announced";
$post_id = $post->ID;
$field = get_field_object($field_key, $post_id);
echo $field['label'] . ': ' . $field['value'];
?>
tried also the echo var_dump($field);
Someone said that the WooCommerce project is not binded to ACF object? That's why I can't access the WooCommerce object via ACF? Your thoughts.
Thanks!
UPDATE (A WORKIG SOLUTION TO SAVE AND RETRIEVE YOUR LABELS NAMES)
I Have make some changes In your code adding hidden imput fields with your label names. When saving/submitting the data, it will save also automatically the label names.
Here is the complete code:
// ADDING A TAB TO WOOCOMMERCE PRODUCT DATA METABOX
add_filter( 'woocommerce_product_data_tabs', 'launch_product_tab_content_tab' , 99 , 1 );
function launch_product_tab_content_tab( $product_data_tabs ) {
$product_data_tabs['launch'] = array(
'label' => __( 'Launch', 'my_text_domain' ),
'target' => 'launch_contents',
);
return $product_data_tabs;
}
// ADDING A FIELDS INSIDE THE TAB IN WOOCOMMERCE PRODUCT DATA METABOX
add_action( 'woocommerce_product_data_panels', 'launch_product_tab_content' );
function launch_product_tab_content() {
global $woocommerce, $post;
// Setting here your labels
$label_text_announced = __( 'Announced(Global)', 'woocommerce' );
$label_text_announced_ph = __( 'Announced(Philippines)', 'woocommerce' );
$label_text_availability_ph = __( 'Availability(Philippines)', 'woocommerce' );
?>
<div id='launch_contents' class='panel woocommerce_options_panel'>
<div class='options_group'>
<?php
woocommerce_wp_text_input( array(
'id' => '_text_announced',
'label' => $label_text_announced,
'desc_tip' => 'true',
'description' => __( 'Year and Month it was announced global', 'woocommerce' ),
'type' => 'text',
) );
woocommerce_wp_text_input( array(
'id' => '_text_announced_ph',
'label' => $label_text_announced_ph,
'desc_tip' => 'true',
'description' => __( 'Year and Month it was announced global', 'woocommerce' ),
'type' => 'text',
) );
woocommerce_wp_text_input( array(
'id' => '_text_availability_ph',
'label' => $label_text_availability_ph,
'desc_tip' => 'true',
'description' => __( 'Schedule date of availability in the Philippines', 'woocommerce' ),
'type' => 'text',
) );
// Addind hidden imputs fields for your labels
echo '<input type="hidden" id="text_announced_label" name="text_announced_label" value="'.$label_text_announced.'" />
<input type="hidden" id="text_announced_ph_label" name="text_announced_ph_label" value="'.$label_text_announced_ph.'" />
<input type="hidden" id="text_availability_ph_label" name="text_availability_ph_label" value="'.$label_text_availability_ph.'" />';
?>
</div>
</div>
<?php
}
// SAVING THE FIELDS DATA from THE TAB IN WOOCOMMERCE PRODUCT DATA METABOX
add_action( 'woocommerce_process_product_meta', 'save_launch_product_tab_content' );
function save_launch_product_tab_content( $post_id ){
// Saving the data with the hidden data labels names
if(isset($_POST['_text_announced'])){
update_post_meta( $post_id, '_text_announced', $_POST['_text_announced'] );
update_post_meta( $post_id, '_text_announced_label', $_POST['text_announced_label'] );
}
if(isset($_POST['_text_announced_ph'])){
update_post_meta( $post_id, '_text_announced_ph', $_POST['_text_announced_ph'] );
update_post_meta( $post_id, '_text_announced_ph_label', $_POST['text_announced_ph_label'] );
}
if(isset($_POST['_text_availability_ph'])){
update_post_meta( $post_id, '_text_availability_ph', $_POST['_text_availability_ph'] );
update_post_meta( $post_id, '_text_availability_ph_label', $_POST['text_availability_ph_label'] );
}
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
Once submitted (SAVED) all the data is set in wp_postmeta table for the current product ID (even the label names), see below what you get in this database table (the ID of the product is 99 here):
So now you can get your label name and the corresponding data value…
Here now a function that will automate that process and set those values in an array:
function get_label_and_value($product_id, $meta_key){
// As the meta_key of the label have the same slug + '_label' we get it here
$key_label = $meta_key . '_label';
// Getting the values
$meta_value = get_post_meta($product_id, $meta_key, true);
$label_name = get_post_meta($product_id, $key_label, true);
// Setting this data in an array:
$result = array('label' => $label_name, 'value' => $meta_value);
// Returning the data array
return $result;
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
Now we can use this function in any PHP file:
<?php
// The product ID
$product_id = $product_id;
// The field key
$field_key = "_text_announced";
// Using our function
$field1 = get_label_and_value($product_id, $field_key);
// Displaying the data (just as you expected to do)
echo $field1['label'] . ': ' . $field1['value'];
?>
And you will get:
Announced(Global): April 2016
So no need of ACF here
This code is tested and works...

How can i make custom field value required ( compulsory ) in woocommerce product page when adding product

I have added custom text box field in my add product page in woocommerce. Now i want to make it required (compulsory). I tried it by passing argument "required"=>true. but it is not working. Please see below code
woocommerce_wp_text_input(
array(
'id' => 'special_price',
'label' => __( 'Wholesaler Price *', 'woocommerce' ),
'placeholder' => '',
'desc_tip' => 'true',
'required' => 'true',
'description' => __( 'Enter wholesaler price here.', 'woocommerce' )
)
);
but it is not making textbox compulsory. Please can anyone tell how can i do this?
For the required HTML5 attribute and other custom attributes woocommerce_wp_text_input() function has custom_attributes option.
woocommerce_wp_text_input(
array(
'id' => 'special_price',
'label' => __( 'Wholesaler Price *', 'woocommerce' ),
'placeholder' => '',
'desc_tip' => 'true',
'custom_attributes' => array( 'required' => 'required' ),
'description' => __( 'Enter wholesaler price here.', 'woocommerce' )
)
);
You can modify the following code as per your need.
// Validate when adding to cart
add_filter( 'woocommerce_add_to_cart_validation', 'woocommerce_add_to_cart_validation_custom', 10, 3 );
/ validation
function woocommerce_add_to_cart_validation_custom($passed, $product_id, $qty){
global $woocommerce;
$option = ''; // your custom field's name
if( isset($_POST[sanitize_title($option)]) && $_POST[sanitize_title($option)] == '' )
$passed = false;
if (!$passed)
$woocommerce->add_error( sprintf( __('"%s" is a required field.', 'woocommerce'), $option) );
return $passed;
}
For even more options while adding a product in the cart you may find How to add a custom text box value to cart session array in Woocommerce my this answer helpful.

Categories