selected not saved ?simple bug ?/ I am beginner - wordpress

I have this function, which gives me dropdown option:
public function edit_tax_image_field( $term ){
$term_id = $term->term_id;
$term_meta = get_option( "taxonomy_$term_id" );
$image = $term_meta['tax_image'] ? $term_meta['tax_image'] : '';
?>
<tr class="form-field">
<th scope="row">
<label for="term_meta[tax_image]">Dropdown menu</label>
<td>
<select name="term_meta[tax_image]" id="term_meta[tax_image]" style="width: 300px;">
<?php
$selected = $image;
$p = '';
$r = '';
foreach ( _s_sample_select_options() as $option ) {
$label = $option['label'];
if ( $selected == $option['value'] ) // Make default first in list
$p = "\n\t<option style=\"padding-right: 10px;\" selected='selected' value='" . esc_attr( $option['value'] ) . "'>$label</option>";
else
$r .= "\n\t<option style=\"padding-right: 10px;\" value='" . esc_attr( $option['value'] ) . "'>$label</option>";
}
echo $p . $r;
?></select>
<p class="description">Some description.</p>
</td>
</th>
</tr><!-- /.form-field -->
<?php
} // edit_tax_image_field
This is my saving function
public function save_tax_meta( $term_id ){
if ( isset( $_POST['term_meta'] ) ) {
$t_id = $term_id;
$term_meta = array();
$term_meta['tax_image'] = isset ( $_POST['term_meta']['tax_image'] ) ? esc_attr( $_POST['term_meta']['tax_image'] ) : '';
// Save the option array.
update_option( "taxonomy_$t_id", $term_meta );
} // if isset( $_POST['term_meta'] )
} // save_tax_meta
I do not know, where should be bug. I am beginner in coding, so ... bug is maybe simple or not.
Solving this problem cost me one day :D and still have no solution :(

try changing
if ( $selected == $option['value'] ) // Make default first in list
$p = "\n\t<option style=\"padding-right: 10px;\" selected='selected' value='" . esc_attr( $option['value'] ) . "'>$label</option>";
to
if ( $selected == $option['value'] ) // Make default first in list
$p .= "\n\t<option style=\"padding-right: 10px;\" selected='selected' value='" . esc_attr( $option['value'] ) . "'>$label</option>";

Related

Adding woocommerce shipping calculator to front end page with shortcode

I am looking to add woocommerce shipping calculator to my delivery policy page with a simple short code. I found a plugin to do that but it's hasn't been updated in 5-7 years and it's filled with bugs and conflict. Can someone look at this code and help me figure out what's wrong with it.
Thanks.
global $shortcode_times;
add_action( 'wp', 'ss_woo_shipping_calculator_ajax' );
function ss_woo_shipping_calculator_ajax() {
if( $_POST["action"] != "ss_woo_shipping_calculator")
return false;
$result = array();
try {
WC()->shipping->load_shipping_methods();
WC()->shipping->reset_shipping();
$country = wc_clean( $_POST['country'] );
$state = wc_clean( isset( $_POST['state'] ) ? $_POST['state'] : '' );
$postcode = apply_filters( 'woocommerce_shipping_calculator_enable_postcode', true ) ? wc_clean( $_POST['postcode'] ) : '';
$city = apply_filters( 'woocommerce_shipping_calculator_enable_city', false ) ? wc_clean( $_POST['city'] ) : '';
if ( $postcode && ! WC_Validation::is_postcode( $postcode, $country ) ) {
throw new Exception( __( 'Please enter a valid postcode / ZIP.', 'woocommerce' ) );
} elseif ( $postcode ) {
$postcode = wc_format_postcode( $postcode, $country );
}
if ( $country ) {
WC()->customer->set_location( $country, $state, $postcode, $city );
WC()->customer->set_shipping_location( $country, $state, $postcode, $city );
} else {
WC()->customer->set_to_base();
WC()->customer->set_shipping_to_base();
}
WC()->customer->set_calculated_shipping( true );
WC()->customer->save();
do_action( 'woocommerce_calculated_shipping' );
$cu = get_woocommerce_currency_symbol();
WC()->shipping->calculate_shipping( WC()->cart->get_shipping_packages() );
$packages = WC()->shipping->get_packages();
if(count($packages ) > 0){
$result["result"] = 1;
$message = "<ul>";
foreach ( $packages as $i => $package ) {
if(count($package['rates']) > 0){
foreach($package['rates'] as $k => $v){
$message .= "<li>".$v->label." <span> - ".$cu." ".$v->cost."</span></li>";
}
}
}
$result["message"] = $message ;
}
} catch ( Exception $e ) {
$result["result"] = 0;
$result["message"] = $e->getMessage() ;
}
echo json_encode($result);
die();
}
function ss_woo_shipping_calculator_shortcode() {
global $shortcode_times;
$shortcode_times++;
if($shortcode_times > 1){
return "";
}
wp_enqueue_script( 'wc-cart' );
ob_start();
do_action( 'woocommerce_before_shipping_calculator' );
?>
<form>
<section class="shipping-calculator-form-shortcode" >
<p class="form-row form-row-wide" id="calc_shipping_country_field">
<select name="calc_shipping_country" id="calc_shipping_country" class="country_to_state" rel="calc_shipping_state">
<option value=""><?php _e( 'Select a country…', 'woocommerce' ); ?></option>
<?php
foreach ( WC()->countries->get_shipping_countries() as $key => $value )
echo '<option value="' . esc_attr( $key ) . '"' . selected( WC()->customer->get_shipping_country(), esc_attr( $key ), false ) . '>' . esc_html( $value ) . '</option>';
?>
</select>
</p>
<p class="form-row form-row-wide" id="calc_shipping_state_field">
<?php
$current_cc = WC()->customer->get_shipping_country();
$current_r = WC()->customer->get_shipping_state();
$states = WC()->countries->get_states( $current_cc );
// Hidden Input
if ( is_array( $states ) && empty( $states ) ) {
?><input type="hidden" name="calc_shipping_state" id="calc_shipping_state" placeholder="<?php esc_attr_e( 'State / County', 'woocommerce' ); ?>" /><?php
// Dropdown Input
} elseif ( is_array( $states ) ) {
?><span>
<select name="calc_shipping_state" id="calc_shipping_state" placeholder="<?php esc_attr_e( 'State / County', 'woocommerce' ); ?>">
<option value=""><?php esc_html_e( 'Select a state…', 'woocommerce' ); ?></option>
<?php
foreach ( $states as $ckey => $cvalue )
echo '<option value="' . esc_attr( $ckey ) . '" ' . selected( $current_r, $ckey, false ) . '>' . esc_html( $cvalue ) . '</option>';
?>
</select>
</span><?php
// Standard Input
} else {
?><input type="text" class="input-text" value="<?php echo esc_attr( $current_r ); ?>" placeholder="<?php esc_attr_e( 'State / County', 'woocommerce' ); ?>" name="calc_shipping_state" id="calc_shipping_state" /><?php
}
?>
</p>
<?php if ( apply_filters( 'woocommerce_shipping_calculator_enable_city', false ) ) : ?>
<p class="form-row form-row-wide" id="calc_shipping_city_field">
<input type="text" class="input-text" value="<?php echo esc_attr( WC()->customer->get_shipping_city() ); ?>" placeholder="<?php esc_attr_e( 'City', 'woocommerce' ); ?>" name="calc_shipping_city" id="calc_shipping_city" />
</p>
<?php endif; ?>
<?php if ( apply_filters( 'woocommerce_shipping_calculator_enable_postcode', true ) ) : ?>
<p class="form-row form-row-wide" id="calc_shipping_postcode_field">
<input type="text" class="input-text" value="<?php echo esc_attr( WC()->customer->get_shipping_postcode() ); ?>" placeholder="<?php esc_attr_e( 'Postcode / ZIP', 'woocommerce' ); ?>" name="calc_shipping_postcode" id="calc_shipping_postcode" />
</p>
<?php endif; ?>
<p><button value="1" class="button ss-woo-shipping-calculator"><?php _e( 'Update totals', 'woocommerce' ); ?></button><span id="ss-woo-shipping-calculator-loading" style="display:none"><img src='<?php echo plugins_url( '/default.gif', __FILE__ ) ?>' /></span></p>
<?php wp_nonce_field( 'woocommerce-cart' ); ?>
<div id="ss-woo-shipping-result">
</div>
</section>
</form>
<script type="text/javascript">
var $s = jQuery.noConflict();
$s(document).ready(function($) {
$(".ss-woo-shipping-calculator").click(function(){
var ajaxurl = "<?php echo admin_url('admin-ajax.php'); ?>";
var country = $(this).parent().parent().find("#calc_shipping_country").val();
var state = $(this).parent().parent().find("#calc_shipping_state").val();
var city = $(this).parent().parent().find("#calc_shipping_city").val();
var postcode = $(this).parent().parent().find("#calc_shipping_postcode").val();
$("#ss-woo-shipping-calculator-loading").show();
var data = {'action': 'ss_woo_shipping_calculator','country': country,'state': state,'city': city,'postcode': postcode};
$.post("<?php echo get_home_url(); ?>", data, function(response) {
$("#ss-woo-shipping-calculator-loading").hide();
response = JSON.parse(response);
if(response.result == 1){
$("#ss-woo-shipping-result").html(response.message);
}else{
alert(response.message);
$("#ss-woo-shipping-result").html("");
}
return false;
});
return false;
});
});
</script>
<?php
do_action( 'woocommerce_after_shipping_calculator' );
$out = ob_get_contents();
ob_end_clean();
return $out;
}
add_shortcode('ss_woo_shipping_calculator', 'ss_woo_shipping_calculator_shortcode');
I need help cleaning the code out and also making it not conflict especially with Elementor.

Show 4 first product attributes

I want to display the first 4 product attributes on each product card.
That code shows me only specific attributes. Any way to get these attributes? Every category has own attributes so I cant do it for every category on the site. Please help me
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
$has_row = false;
$attributes = $product->get_attributes();
ob_start();
?>
<div class="product_attributes">
<?php foreach ( $attributes as $attribute ) :
if ( empty( $attribute['is_visible'] ) || ( $attribute['is_taxonomy'] && ! taxonomy_exists( $attribute['name'] ) ) )
continue;
$values = wc_get_product_terms( $product->get_id(), $attribute['name'], array( 'fields' => 'names' ) );
$att_val = apply_filters( 'woocommerce_attribute', wpautop( wptexturize( implode( ', ', $values ) ) ), $attribute, $values );
if( empty( $att_val ) )
continue;
$has_row = true;
?>
<div class="col">
<div class="att_label"><?php echo wc_attribute_label( $attribute['name'] ); ?></div>
<div class="att_value"><?php echo $att_val; ?></div><!-- .att_value -->
</div><!-- .col -->
<?php endforeach; ?>
</div><!-- .product_attributes -->
<?php
if ( $has_row ) {
echo ob_get_clean();
} else {
ob_end_clean();
}
So I wrote other function:
if( $_product->has_attributes() ){
// Initializing
$attributes = array();
// Loop through product attributes
$i = 0;
foreach( $_product->get_attributes() as $taxonomy => $attribute ){
// The product attribute label name
$attribute_name = get_taxonomy( $taxonomy )->labels->singular_name;
// Set each product attribute with its values in an array
// $attributes[] = '<strong>'.$attribute_name.'</strong>: '.$_product->get_attribute($taxonomy);
?>
<div class="prodAttr">
<p class="prodAttr__title"><?php echo $attribute_name?></p>
<p class="prodAttr__value"><?php echo $_product->get_attribute($taxonomy) ?></p>
</div>
<?php
$i++;
if ($i == 4) break;
}
// Display (output)
// echo '<div class="product-attributes"><span>'. implode( '</span> <span>', $attributes ) . '</span></div>';
}
It works. Closed

Class Variations Label Out Stock Woocommerce

I need to add a css style class for only "label" products that are not in stock.
Example Original Code:
<label class="radio-label sw-radio-variation sw-radio-variation-2" title="l" for="l_2">
The code I want:
<label class="out-stock radio-label sw-radio-variation sw-radio-variation-2" title="l" for="l_2">
As you see add to the CSS code out-stock
Thanks
Edit: My product-variation.php is
<?php
/*
** Product variation hook
*/
add_filter( 'woocommerce_dropdown_variation_attribute_options_html', 'sw_woocommerce_custom_variation', 10, 2 );
function sw_woocommerce_custom_variation( $html, $args ){
$options = $args['options'];
$product = $args['product'];
$attribute = $args['attribute'];
$name = $args['name'] ? $args['name'] : 'attribute_' . sanitize_title( $attribute );
$id = $args['id'] ? $args['id'] : sanitize_title( $attribute );
$class = $args['class'];
if ( empty( $options ) && ! empty( $product ) && ! empty( $attribute ) ) {
$attributes = $product->get_variation_attributes();
$options = $attributes[ $attribute ];
}
$html = '';
if ( ! empty( $options ) ) {
$html .= '<div class="sw-custom-variation">';
if ( $product && taxonomy_exists( $attribute ) ) {
// Get terms if this is a taxonomy - ordered. We need the names too.
$terms = wc_get_product_terms( $product->get_id(), $attribute, array( 'fields' => 'all' ) );
foreach ( $terms as $key => $term ) {
$color = get_term_meta( $term->term_id, 'sw_variation_color', true );
$active = ( checked( sanitize_title( $args['selected'] ), $term->slug, false ) ) ? ' selected' : '';
$attributes = ( preg_match( '/color|colors/', $attribute, $match ) && $color != '' ) ? 'class="variation-color" style="background: '. esc_attr( $color ) .'"' : '';
if ( in_array( $term->slug, $options ) ) {
$html .= '<label class="radio-label sw-radio-variation sw-radio-variation-'. esc_attr( $key .' '. $active ) .'" title="'. esc_attr( $term->slug ) .'" for="'. esc_attr( $term->slug . '_' . $key ) . '">';
$html .= '<input type="radio" id="'. esc_attr( $term->slug . '_' . $key ) .'" name="' . esc_attr( $name ) . '" data-attribute_name="attribute_' . esc_attr( sanitize_title( $attribute ) ) . '" value="' . esc_attr( $term->slug ) . '" '. checked( sanitize_title( $args['selected'] ), $term->slug, false ) .'/>';
$html .= '<span '. $attributes .'>'. $term->name .'</span>';
$html .= '</label>';
}
}
}else {
foreach ( $options as $key => $option ) {
// This handles < 2.4.0 bw compatibility where text attributes were not sanitized.
$checked = sanitize_title( $args['selected'] ) === $args['selected'] ? checked( $args['selected'], sanitize_title( $option ), false ) : checked( $args['selected'], $option, false );
$active = ( $checked ) ? 'selected' : '';
$html .= '<label class="radio-label sw-radio-variation sw-radio-variation-'. esc_attr( $key .' '. $active ) .'" title="'. esc_attr( $option ) .'" for="'. esc_attr( $option . '_' . $key ) . '">';
$html .= '<input type="radio" id="'. esc_attr( $option . '_' . $key ) .'" name="' . esc_attr( $name ) . '" data-attribute_name="attribute_' . esc_attr( sanitize_title( $attribute ) ) . '" value="' . esc_attr( $option ) . '" '. $checked .'/>';
$html .= '<span>'. $option .'</span>';
$html .= '</label>';
}
}
$html .= '</div>';
}
return $html;
}
/*
** Action hook to color
*/
$sw_attribute_taxonomies = wc_get_attribute_taxonomies();
if ( ! empty( $sw_attribute_taxonomies ) ) {
foreach( $sw_attribute_taxonomies as $attr ){
if( preg_match( '/color|colors/', $attr->attribute_name, $match ) ){
add_action( 'pa_'. $attr->attribute_name .'_add_form_fields', 'sw_woocommerce_variation_fields', 200 );
add_action( 'pa_'. $attr->attribute_name .'_edit_form_fields', 'sw_woocommerce_edit_variation_fields', 200 );
add_action( 'created_term', 'sw_woocommerce_save_variation_fields', 10, 3 );
add_action( 'edit_terms', 'sw_woocommerce_save_variation_fields', 10, 3 );
/* Enqueue Admin js */
add_action( 'admin_enqueue_scripts', 'sw_woocommerce_variation_color_script' );
}
}
}
/*
** Create color
*/
function sw_woocommerce_variation_fields() {
?>
<div class="form-field custom-picker">
<label for="sw_variation_color"><?php _e( 'Color', 'sw_woocommerce' ); ?></label>
<input name="sw_variation_color" id="sw_variation_color" type="text" value="" size="40" class="category-colorpicker"/>
</div>
<?php
}
function sw_woocommerce_edit_variation_fields( $term ) {
$sw_variation_color = get_term_meta( $term->term_id, 'sw_variation_color', true );
?>
<tr class="form-field custom-picker custom-picker-edit">
<th scope="row" valign="top"><label for="sw_variation_color"><?php _e( 'Color', 'sw_woocommerce' ); ?></label></th>
<td>
<input name="sw_variation_color" id="sw_variation_color" type="text" value="<?php echo esc_attr( $sw_variation_color ) ?>" size="40" class="category-colorpicker"/>
</td>
</tr>
<?php
}
/** Save Custom Field Of Category Form */
function sw_woocommerce_save_variation_fields( $term_id, $tt_id = '', $taxonomy = '', $prev_value = '' ) {
if ( isset( $_POST['sw_variation_color'] ) ) {
$term_value = esc_attr( $_POST['sw_variation_color'] );
update_term_meta( $term_id, 'sw_variation_color', $term_value, $prev_value );
}
}
function sw_woocommerce_variation_color_script(){
wp_enqueue_style( 'wp-color-picker' );
wp_enqueue_script('category_color_picker_js', WCURL . '/js/admin/category_color_picker.js', array( 'wp-color-picker' ), false, true);
}
As you can see on line 60 you will find the labels
Will there be any code to add a custom CSS to these labels that create the variables?
************** SOLUTION ***********
<?php
// Adiccional Class For Label Variations
function get_variation_stock_text( $product, $name, $term_slug ){
foreach ( $product->get_available_variations() as $variation ){
if($variation['attributes'][$name] == $term_slug ){
$is_in_stock = $variation['is_in_stock'];
$stock_qty = get_post_meta($variation['variation_id'], '_stock', true);
}
}
$in_stock = ' '.__("katayainstock", "woocommerce").'';
$out_of_stock = ' '.__("katayaoutstock", "woocommerce").'';
return $is_in_stock == 1 ? $in_stock : $out_of_stock;
}
/**
* Product variation hook
*/
add_filter( 'woocommerce_dropdown_variation_attribute_options_html', 'sw_woocommerce_custom_variation', 10, 2 );
function sw_woocommerce_custom_variation( $html, $args ) {
$options = $args['options'];
$product = $args['product'];
$attribute = $args['attribute'];
$name = $args['name'] ? $args['name'] : 'attribute_' . sanitize_title( $attribute );
$id = $args['id'] ? $args['id'] : sanitize_title( $attribute );
$class = $args['class'];
if ( empty( $options ) && ! empty( $product ) && ! empty( $attribute ) ) {
$attributes = $product->get_variation_attributes();
$options = $attributes[ $attribute ];
}
$html = '';
if ( ! empty( $options ) ) {
$html .= '<div class="sw-custom-variation">';
if ( $product && taxonomy_exists( $attribute ) ) {
// Get terms if this is a taxonomy - ordered. We need the names too.
$terms = wc_get_product_terms( $product->get_id(), $attribute, array( 'fields' => 'all' ) );
foreach ( $terms as $key => $term ) {
$color = get_term_meta( $term->term_id, 'sw_variation_color', true );
$active = checked( sanitize_title( $args['selected'] ), $term->slug, false ) ? ' selected' : '';
$attributes = ( preg_match( '/color|colors/', $attribute, $match ) && $color !== '' ) ? 'class="variation-color" style="background: ' . esc_attr( $color ) . '"' : '';
if ( in_array( $term->slug, $options, true ) ) {
$stock_text = get_variation_stock_text( $product, $name, $term->slug );
$html .= '<label class="' . $stock_text . ' radio-label sw-radio-variation sw-radio-variation-' . esc_attr( $key . ' ' . $active ) . '" title="' . esc_attr( $term->slug ) . '" for="' . esc_attr( $term->slug . '_' . $key ) . '">';
$html .= '<input type="radio" id="' . esc_attr( $term->slug . '_' . $key ) . '" name="' . esc_attr( $name ) . '" data-attribute_name="attribute_' . esc_attr( sanitize_title( $attribute ) ) . '" value="' . esc_attr( $term->slug ) . '" ' . checked( sanitize_title( $args['selected'] ), $term->slug, false ) . '/>';
$html .= '<span ' . $attributes . '>' . $term->name . '</span>';
$html .= '</label>';
}
}
} else {
foreach ( $options as $key => $option ) {
// This handles < 2.4.0 bw compatibility where text attributes were not sanitized.
$checked = sanitize_title( $args['selected'] ) === $args['selected'] ? checked( $args['selected'], sanitize_title( $option ), false ) : checked( $args['selected'], $option, false );
$active = ( $checked ) ? 'selected' : '';
$html .= '<label class="radio-label sw-radio-variation sw-radio-variation-' . esc_attr( $key . ' ' . $active ) . '" title="' . esc_attr( $option ) . '" for="' . esc_attr( $option . '_' . $key ) . '">';
$html .= '<input type="radio" id="' . esc_attr( $option . '_' . $key ) . '" name="' . esc_attr( $name ) . '" data-attribute_name="attribute_' . esc_attr( sanitize_title( $attribute ) ) . '" value="' . esc_attr( $option ) . '" ' . $checked . '/>';
$html .= '<span>' . $option . '</span>';
$html .= '</label>';
}
}
$html .= '</div>';
}
return $html;
}
/**
* Action hook color
*/
$sw_attribute_taxonomies = wc_get_attribute_taxonomies();
if ( ! empty( $sw_attribute_taxonomies ) ) {
foreach ( $sw_attribute_taxonomies as $attr ) {
if ( preg_match( '/color|colors/', $attr->attribute_name, $match ) ) {
add_action( 'pa_' . $attr->attribute_name . '_add_form_fields', 'sw_woocommerce_variation_fields', 200 );
add_action( 'pa_' . $attr->attribute_name . '_edit_form_fields', 'sw_woocommerce_edit_variation_fields', 200 );
add_action( 'created_term', 'sw_woocommerce_save_variation_fields', 10, 3 );
add_action( 'edit_terms', 'sw_woocommerce_save_variation_fields', 10, 3 );
add_action( 'admin_enqueue_scripts', 'sw_woocommerce_variation_color_script' );
}
}
}
/**
* Create color
*/
function sw_woocommerce_variation_fields() { ?>
<div class="form-field custom-picker">
<label for="sw_variation_color"><?php _e( 'Color', 'sw_woocommerce' ); ?></label>
<input name="sw_variation_color" id="sw_variation_color" type="text" value="" size="40"
class="category-colorpicker"/>
</div>
<?php
}
/**
* #param $term
*/
function sw_woocommerce_edit_variation_fields( $term ) {
$sw_variation_color = get_term_meta( $term->term_id, 'sw_variation_color', true ); ?>
<tr class="form-field custom-picker custom-picker-edit">
<th scope="row" valign="top"><label
for="sw_variation_color"><?php _e( 'Color', 'sw_woocommerce' ); ?></label></th>
<td>
<input name="sw_variation_color" id="sw_variation_color" type="text"
value="<?php echo esc_attr( $sw_variation_color ) ?>" size="40" class="category-colorpicker"/>
</td>
</tr>
<?php
}
/**
* Save custom field of category form
*
* #param $term_id
* #param string $tt_id
* #param string $taxonomy
* #param string $prev_value
*/
function sw_woocommerce_save_variation_fields( $term_id, $tt_id = '', $taxonomy = '', $prev_value = '' ) {
if ( isset( $_POST['sw_variation_color'] ) ) {
$term_value = esc_attr( $_POST['sw_variation_color'] );
update_term_meta( $term_id, 'sw_variation_color', $term_value, $prev_value );
}
}
function sw_woocommerce_variation_color_script() {
wp_enqueue_style( 'wp-color-picker' );
wp_enqueue_script( 'category_color_picker_js', WCURL . '/js/admin/category_color_picker.js', array( 'wp-color-picker' ), false, true );
}
Here try this. And one tip, improve your code formatting because one day you need to edit this again.
<?php
/**
* Product variation hook
*/
add_filter( 'woocommerce_dropdown_variation_attribute_options_html', 'sw_woocommerce_custom_variation', 10, 2 );
function sw_woocommerce_custom_variation( $html, $args ) {
$options = $args['options'];
$product = $args['product'];
$attribute = $args['attribute'];
$name = $args['name'] ? $args['name'] : 'attribute_' . sanitize_title( $attribute );
$id = $args['id'] ? $args['id'] : sanitize_title( $attribute );
$class = $args['class'];
if ( empty( $options ) && ! empty( $product ) && ! empty( $attribute ) ) {
$attributes = $product->get_variation_attributes();
$options = $attributes[ $attribute ];
}
$html = '';
if ( ! empty( $options ) ) {
$html .= '<div class="sw-custom-variation">';
if ( $product && taxonomy_exists( $attribute ) ) {
//Get product stock
$stock = $product->get_stock_quantity();
// Get terms if this is a taxonomy - ordered. We need the names too.
$terms = wc_get_product_terms( $product->get_id(), $attribute, array( 'fields' => 'all' ) );
foreach ( $terms as $key => $term ) {
$color = get_term_meta( $term->term_id, 'sw_variation_color', true );
$active = checked( sanitize_title( $args['selected'] ), $term->slug, false ) ? ' selected' : '';
$attributes = ( preg_match( '/color|colors/', $attribute, $match ) && $color !== '' ) ? 'class="variation-color" style="background: ' . esc_attr( $color ) . '"' : '';
if ( in_array( $term->slug, $options, true ) ) {
$additional_class = '';
if ( ! empty( $stock ) && $stock < 1 ) {
$additional_class = 'out-stock';
}
$html .= '<label class="' . $additional_class . ' radio-label sw-radio-variation sw-radio-variation-' . esc_attr( $key . ' ' . $active ) . '" title="' . esc_attr( $term->slug ) . '" for="' . esc_attr( $term->slug . '_' . $key ) . '">';
$html .= '<input type="radio" id="' . esc_attr( $term->slug . '_' . $key ) . '" name="' . esc_attr( $name ) . '" data-attribute_name="attribute_' . esc_attr( sanitize_title( $attribute ) ) . '" value="' . esc_attr( $term->slug ) . '" ' . checked( sanitize_title( $args['selected'] ), $term->slug, false ) . '/>';
$html .= '<span ' . $attributes . '>' . $term->name . '</span>';
$html .= '</label>';
}
}
} else {
foreach ( $options as $key => $option ) {
// This handles < 2.4.0 bw compatibility where text attributes were not sanitized.
$checked = sanitize_title( $args['selected'] ) === $args['selected'] ? checked( $args['selected'], sanitize_title( $option ), false ) : checked( $args['selected'], $option, false );
$active = ( $checked ) ? 'selected' : '';
$html .= '<label class="radio-label sw-radio-variation sw-radio-variation-' . esc_attr( $key . ' ' . $active ) . '" title="' . esc_attr( $option ) . '" for="' . esc_attr( $option . '_' . $key ) . '">';
$html .= '<input type="radio" id="' . esc_attr( $option . '_' . $key ) . '" name="' . esc_attr( $name ) . '" data-attribute_name="attribute_' . esc_attr( sanitize_title( $attribute ) ) . '" value="' . esc_attr( $option ) . '" ' . $checked . '/>';
$html .= '<span>' . $option . '</span>';
$html .= '</label>';
}
}
$html .= '</div>';
}
return $html;
}
/**
* Action hook color
*/
$sw_attribute_taxonomies = wc_get_attribute_taxonomies();
if ( ! empty( $sw_attribute_taxonomies ) ) {
foreach ( $sw_attribute_taxonomies as $attr ) {
if ( preg_match( '/color|colors/', $attr->attribute_name, $match ) ) {
add_action( 'pa_' . $attr->attribute_name . '_add_form_fields', 'sw_woocommerce_variation_fields', 200 );
add_action( 'pa_' . $attr->attribute_name . '_edit_form_fields', 'sw_woocommerce_edit_variation_fields', 200 );
add_action( 'created_term', 'sw_woocommerce_save_variation_fields', 10, 3 );
add_action( 'edit_terms', 'sw_woocommerce_save_variation_fields', 10, 3 );
add_action( 'admin_enqueue_scripts', 'sw_woocommerce_variation_color_script' );
}
}
}
/**
* Create color
*/
function sw_woocommerce_variation_fields() { ?>
<div class="form-field custom-picker">
<label for="sw_variation_color"><?php _e( 'Color', 'sw_woocommerce' ); ?></label>
<input name="sw_variation_color" id="sw_variation_color" type="text" value="" size="40"
class="category-colorpicker"/>
</div>
<?php
}
/**
* #param $term
*/
function sw_woocommerce_edit_variation_fields( $term ) {
$sw_variation_color = get_term_meta( $term->term_id, 'sw_variation_color', true ); ?>
<tr class="form-field custom-picker custom-picker-edit">
<th scope="row" valign="top"><label
for="sw_variation_color"><?php _e( 'Color', 'sw_woocommerce' ); ?></label></th>
<td>
<input name="sw_variation_color" id="sw_variation_color" type="text"
value="<?php echo esc_attr( $sw_variation_color ) ?>" size="40" class="category-colorpicker"/>
</td>
</tr>
<?php
}
/**
* Save custom field of category form
*
* #param $term_id
* #param string $tt_id
* #param string $taxonomy
* #param string $prev_value
*/
function sw_woocommerce_save_variation_fields( $term_id, $tt_id = '', $taxonomy = '', $prev_value = '' ) {
if ( isset( $_POST['sw_variation_color'] ) ) {
$term_value = esc_attr( $_POST['sw_variation_color'] );
update_term_meta( $term_id, 'sw_variation_color', $term_value, $prev_value );
}
}
function sw_woocommerce_variation_color_script() {
wp_enqueue_style( 'wp-color-picker' );
wp_enqueue_script( 'category_color_picker_js', WCURL . '/js/admin/category_color_picker.js', array( 'wp-color-picker' ), false, true );
}

Add Class Variation Woocommerce Out Stock

I need to add a css style class for only "label" products that are not in stock.
Example Original Code:
<label class="radio-label sw-radio-variation sw-radio-variation-2" title="l" for="l_2">
The code I want:
<label class="out-stock radio-label sw-radio-variation sw-radio-variation-2" title="l" for="l_2">
As you see add to the CSS code out-stock
Thanks
Edit: My product-variation.php is
<?php
/*
** Product variation hook
*/
add_filter( 'woocommerce_dropdown_variation_attribute_options_html', 'sw_woocommerce_custom_variation', 10, 2 );
function sw_woocommerce_custom_variation( $html, $args ){
$options = $args['options'];
$product = $args['product'];
$attribute = $args['attribute'];
$name = $args['name'] ? $args['name'] : 'attribute_' . sanitize_title( $attribute );
$id = $args['id'] ? $args['id'] : sanitize_title( $attribute );
$class = $args['class'];
if ( empty( $options ) && ! empty( $product ) && ! empty( $attribute ) ) {
$attributes = $product->get_variation_attributes();
$options = $attributes[ $attribute ];
}
$html = '';
if ( ! empty( $options ) ) {
$html .= '<div class="sw-custom-variation">';
if ( $product && taxonomy_exists( $attribute ) ) {
// Get terms if this is a taxonomy - ordered. We need the names too.
$terms = wc_get_product_terms( $product->get_id(), $attribute, array( 'fields' => 'all' ) );
foreach ( $terms as $key => $term ) {
$color = get_term_meta( $term->term_id, 'sw_variation_color', true );
$active = ( checked( sanitize_title( $args['selected'] ), $term->slug, false ) ) ? ' selected' : '';
$attributes = ( preg_match( '/color|colors/', $attribute, $match ) && $color != '' ) ? 'class="variation-color" style="background: '. esc_attr( $color ) .'"' : '';
if ( in_array( $term->slug, $options ) ) {
$html .= '<label class="radio-label sw-radio-variation sw-radio-variation-'. esc_attr( $key .' '. $active ) .'" title="'. esc_attr( $term->slug ) .'" for="'. esc_attr( $term->slug . '_' . $key ) . '">';
$html .= '<input type="radio" id="'. esc_attr( $term->slug . '_' . $key ) .'" name="' . esc_attr( $name ) . '" data-attribute_name="attribute_' . esc_attr( sanitize_title( $attribute ) ) . '" value="' . esc_attr( $term->slug ) . '" '. checked( sanitize_title( $args['selected'] ), $term->slug, false ) .'/>';
$html .= '<span '. $attributes .'>'. $term->name .'</span>';
$html .= '</label>';
}
}
}else {
foreach ( $options as $key => $option ) {
// This handles < 2.4.0 bw compatibility where text attributes were not sanitized.
$checked = sanitize_title( $args['selected'] ) === $args['selected'] ? checked( $args['selected'], sanitize_title( $option ), false ) : checked( $args['selected'], $option, false );
$active = ( $checked ) ? 'selected' : '';
$html .= '<label class="radio-label sw-radio-variation sw-radio-variation-'. esc_attr( $key .' '. $active ) .'" title="'. esc_attr( $option ) .'" for="'. esc_attr( $option . '_' . $key ) . '">';
$html .= '<input type="radio" id="'. esc_attr( $option . '_' . $key ) .'" name="' . esc_attr( $name ) . '" data-attribute_name="attribute_' . esc_attr( sanitize_title( $attribute ) ) . '" value="' . esc_attr( $option ) . '" '. $checked .'/>';
$html .= '<span>'. $option .'</span>';
$html .= '</label>';
}
}
$html .= '</div>';
}
return $html;
}
/*
** Action hook to color
*/
$sw_attribute_taxonomies = wc_get_attribute_taxonomies();
if ( ! empty( $sw_attribute_taxonomies ) ) {
foreach( $sw_attribute_taxonomies as $attr ){
if( preg_match( '/color|colors/', $attr->attribute_name, $match ) ){
add_action( 'pa_'. $attr->attribute_name .'_add_form_fields', 'sw_woocommerce_variation_fields', 200 );
add_action( 'pa_'. $attr->attribute_name .'_edit_form_fields', 'sw_woocommerce_edit_variation_fields', 200 );
add_action( 'created_term', 'sw_woocommerce_save_variation_fields', 10, 3 );
add_action( 'edit_terms', 'sw_woocommerce_save_variation_fields', 10, 3 );
/* Enqueue Admin js */
add_action( 'admin_enqueue_scripts', 'sw_woocommerce_variation_color_script' );
}
}
}
/*
** Create color
*/
function sw_woocommerce_variation_fields() {
?>
<div class="form-field custom-picker">
<label for="sw_variation_color"><?php _e( 'Color', 'sw_woocommerce' ); ?></label>
<input name="sw_variation_color" id="sw_variation_color" type="text" value="" size="40" class="category-colorpicker"/>
</div>
<?php
}
function sw_woocommerce_edit_variation_fields( $term ) {
$sw_variation_color = get_term_meta( $term->term_id, 'sw_variation_color', true );
?>
<tr class="form-field custom-picker custom-picker-edit">
<th scope="row" valign="top"><label for="sw_variation_color"><?php _e( 'Color', 'sw_woocommerce' ); ?></label></th>
<td>
<input name="sw_variation_color" id="sw_variation_color" type="text" value="<?php echo esc_attr( $sw_variation_color ) ?>" size="40" class="category-colorpicker"/>
</td>
</tr>
<?php
}
/** Save Custom Field Of Category Form */
function sw_woocommerce_save_variation_fields( $term_id, $tt_id = '', $taxonomy = '', $prev_value = '' ) {
if ( isset( $_POST['sw_variation_color'] ) ) {
$term_value = esc_attr( $_POST['sw_variation_color'] );
update_term_meta( $term_id, 'sw_variation_color', $term_value, $prev_value );
}
}
function sw_woocommerce_variation_color_script(){
wp_enqueue_style( 'wp-color-picker' );
wp_enqueue_script('category_color_picker_js', WCURL . '/js/admin/category_color_picker.js', array( 'wp-color-picker' ), false, true);
}
As you can see on line 60 you will find the labels
Will there be any code to add a custom CSS to these labels that create the variables?
Thanks
************** SOLUTION ***********
<?php
// Adiccional Class For Label Variations
function get_variation_stock_text( $product, $name, $term_slug ){
foreach ( $product->get_available_variations() as $variation ){
if($variation['attributes'][$name] == $term_slug ){
$is_in_stock = $variation['is_in_stock'];
$stock_qty = get_post_meta($variation['variation_id'], '_stock', true);
}
}
$in_stock = ' '.__("katayainstock", "woocommerce").'';
$out_of_stock = ' '.__("katayaoutstock", "woocommerce").'';
return $is_in_stock == 1 ? $in_stock : $out_of_stock;
}
/**
* Product variation hook
*/
add_filter( 'woocommerce_dropdown_variation_attribute_options_html', 'sw_woocommerce_custom_variation', 10, 2 );
function sw_woocommerce_custom_variation( $html, $args ) {
$options = $args['options'];
$product = $args['product'];
$attribute = $args['attribute'];
$name = $args['name'] ? $args['name'] : 'attribute_' . sanitize_title( $attribute );
$id = $args['id'] ? $args['id'] : sanitize_title( $attribute );
$class = $args['class'];
if ( empty( $options ) && ! empty( $product ) && ! empty( $attribute ) ) {
$attributes = $product->get_variation_attributes();
$options = $attributes[ $attribute ];
}
$html = '';
if ( ! empty( $options ) ) {
$html .= '<div class="sw-custom-variation">';
if ( $product && taxonomy_exists( $attribute ) ) {
// Get terms if this is a taxonomy - ordered. We need the names too.
$terms = wc_get_product_terms( $product->get_id(), $attribute, array( 'fields' => 'all' ) );
foreach ( $terms as $key => $term ) {
$color = get_term_meta( $term->term_id, 'sw_variation_color', true );
$active = checked( sanitize_title( $args['selected'] ), $term->slug, false ) ? ' selected' : '';
$attributes = ( preg_match( '/color|colors/', $attribute, $match ) && $color !== '' ) ? 'class="variation-color" style="background: ' . esc_attr( $color ) . '"' : '';
if ( in_array( $term->slug, $options, true ) ) {
$stock_text = get_variation_stock_text( $product, $name, $term->slug );
$html .= '<label class="' . $stock_text . ' radio-label sw-radio-variation sw-radio-variation-' . esc_attr( $key . ' ' . $active ) . '" title="' . esc_attr( $term->slug ) . '" for="' . esc_attr( $term->slug . '_' . $key ) . '">';
$html .= '<input type="radio" id="' . esc_attr( $term->slug . '_' . $key ) . '" name="' . esc_attr( $name ) . '" data-attribute_name="attribute_' . esc_attr( sanitize_title( $attribute ) ) . '" value="' . esc_attr( $term->slug ) . '" ' . checked( sanitize_title( $args['selected'] ), $term->slug, false ) . '/>';
$html .= '<span ' . $attributes . '>' . $term->name . '</span>';
$html .= '</label>';
}
}
} else {
foreach ( $options as $key => $option ) {
// This handles < 2.4.0 bw compatibility where text attributes were not sanitized.
$checked = sanitize_title( $args['selected'] ) === $args['selected'] ? checked( $args['selected'], sanitize_title( $option ), false ) : checked( $args['selected'], $option, false );
$active = ( $checked ) ? 'selected' : '';
$html .= '<label class="radio-label sw-radio-variation sw-radio-variation-' . esc_attr( $key . ' ' . $active ) . '" title="' . esc_attr( $option ) . '" for="' . esc_attr( $option . '_' . $key ) . '">';
$html .= '<input type="radio" id="' . esc_attr( $option . '_' . $key ) . '" name="' . esc_attr( $name ) . '" data-attribute_name="attribute_' . esc_attr( sanitize_title( $attribute ) ) . '" value="' . esc_attr( $option ) . '" ' . $checked . '/>';
$html .= '<span>' . $option . '</span>';
$html .= '</label>';
}
}
$html .= '</div>';
}
return $html;
}
/**
* Action hook color
*/
$sw_attribute_taxonomies = wc_get_attribute_taxonomies();
if ( ! empty( $sw_attribute_taxonomies ) ) {
foreach ( $sw_attribute_taxonomies as $attr ) {
if ( preg_match( '/color|colors/', $attr->attribute_name, $match ) ) {
add_action( 'pa_' . $attr->attribute_name . '_add_form_fields', 'sw_woocommerce_variation_fields', 200 );
add_action( 'pa_' . $attr->attribute_name . '_edit_form_fields', 'sw_woocommerce_edit_variation_fields', 200 );
add_action( 'created_term', 'sw_woocommerce_save_variation_fields', 10, 3 );
add_action( 'edit_terms', 'sw_woocommerce_save_variation_fields', 10, 3 );
add_action( 'admin_enqueue_scripts', 'sw_woocommerce_variation_color_script' );
}
}
}
/**
* Create color
*/
function sw_woocommerce_variation_fields() { ?>
<div class="form-field custom-picker">
<label for="sw_variation_color"><?php _e( 'Color', 'sw_woocommerce' ); ?></label>
<input name="sw_variation_color" id="sw_variation_color" type="text" value="" size="40"
class="category-colorpicker"/>
</div>
<?php
}
/**
* #param $term
*/
function sw_woocommerce_edit_variation_fields( $term ) {
$sw_variation_color = get_term_meta( $term->term_id, 'sw_variation_color', true ); ?>
<tr class="form-field custom-picker custom-picker-edit">
<th scope="row" valign="top"><label
for="sw_variation_color"><?php _e( 'Color', 'sw_woocommerce' ); ?></label></th>
<td>
<input name="sw_variation_color" id="sw_variation_color" type="text"
value="<?php echo esc_attr( $sw_variation_color ) ?>" size="40" class="category-colorpicker"/>
</td>
</tr>
<?php
}
/**
* Save custom field of category form
*
* #param $term_id
* #param string $tt_id
* #param string $taxonomy
* #param string $prev_value
*/
function sw_woocommerce_save_variation_fields( $term_id, $tt_id = '', $taxonomy = '', $prev_value = '' ) {
if ( isset( $_POST['sw_variation_color'] ) ) {
$term_value = esc_attr( $_POST['sw_variation_color'] );
update_term_meta( $term_id, 'sw_variation_color', $term_value, $prev_value );
}
}
function sw_woocommerce_variation_color_script() {
wp_enqueue_style( 'wp-color-picker' );
wp_enqueue_script( 'category_color_picker_js', WCURL . '/js/admin/category_color_picker.js', array( 'wp-color-picker' ), false, true );
}

How can I save a custom field of an attribute in Woocommerce?

Old
I am trying to create a custom field in the product attributes in Woocommerce. This to be able to select if an attribute is highlighted or not. For example:
https://i.stack.imgur.com/Ge76B.png
What I want to do is that the field that I specify in backend as highlighted is displayed in a certain way in the frontend.
So far I have been able to add the field, but I have not managed to figure out how to save it. This is what I have:
add_action('woocommerce_after_product_attribute_settings','wcb_add_product_attribute_is_highlighted', 10, 2);
add_filter( 'woocommerce_admin_meta_boxes_prepare_attribute', 'wcb_admin_meta_boxes_prepare_attribute', 10, 3);
function get_attribute_highlighted($id, $i) {
return get_post_meta( 1, "attribute_".$id."_highlighted_".$i, true);
}
function wcb_add_product_attribute_is_highlighted($attribute, $i=0) {
$value = get_attribute_highlighted($attribute->get_id(), $i); ?>
<tr>
<td>
<div class="enable_variation show_if_canopytour show_if_variable_canopytour">
<label><input type="checkbox" class="checkbox" <?php checked( $value, true ); ?> name="attribute_highlighted[<?php echo esc_attr( $i ); ?>]" value="1" /> <?php esc_html_e( 'Highlight attribute', $this->wcb ); ?></label>
</div>
</td>
</tr>
<?php
}
function wcb_admin_meta_boxes_prepare_attribute($attribute, $data, $i=0) {
// updated
if(array_key_exists("attribute_highlighted", $data) && is_array($data["attribute_highlighted"])) {
update_post_meta( 1, "attribute_".$attribute->get_id()."_highlighted_".$i, wc_string_to_bool($data["attribute_highlighted"][$i]) );
}
}
I tried the woocommerce_admin_meta_boxes_prepare_attribute filter using the offsetSet and offsetGet methods of the WC_Product_Attribute class but I can not understand how it works. I could not make it save my custom value.
Upgrade
I changed the woocommerce_admin_meta_boxes_prepare_attribute filter by the wp_ajax_woocommerce_save_attributes action and it seems to work. Now I have the problem that it is not updated after saving for the first time.
I explain the current problem: I have a checkbox that when clicked is activated, I save and when reloading the state it is maintained. If now I want to deactivate it, after saving the state it is not kept as disabled, it is put back as activated.
This is the updated code:
add_action('woocommerce_after_product_attribute_settings', 'wcb_add_product_attribute_is_highlighted', 10, 2);
add_action('wp_ajax_woocommerce_save_attributes', 'wcb_ajax_woocommerce_save_attributes', 10);
function get_attribute_highlighted($id, $i) {
global $post;
$id = sanitize_title($id);
$id = strtolower($id);
$val = get_post_meta( $post->ID, "attribute_".$id."_highlighted_".$i, true);
return !empty($val) ? $val : false;
}
function wcb_add_product_attribute_is_highlighted($attribute, $i=0) {
$value = get_attribute_highlighted($attribute->get_name(), $i); ?>
<tr>
<td>
<div class="enable_highlighted show_if_canopytour show_if_variable_canopytour">
<label><input type="checkbox" class="checkbox" <?php checked( $value, true ); ?> name="attribute_highlighted[<?php echo esc_attr( $i ); ?>]" value="1" /> <?php esc_html_e( 'Highlight attribute', $this->wcb ); ?></label>
</div>
</td>
</tr>
<?php
}
function wcb_ajax_woocommerce_save_attributes() {
check_ajax_referer( 'save-attributes', 'security' );
parse_str( $_POST['data'], $data );
$post_id = absint( $_POST['post_id'] );
if(array_key_exists("attribute_highlighted", $data) && is_array($data["attribute_highlighted"])) {
foreach($data["attribute_highlighted"] as $i => $val) {
$attr_name = sanitize_title($data["attribute_names"][$i]);
$attr_name = strtolower($attr_name);
update_post_meta( $post_id, "attribute_".$attr_name."_highlighted_".$i, wc_string_to_bool($val) );
}
}
}
Check Ink's answer
Outdated
I have found the solution to my problem. I share the code in case someone is useful. Regards!
add_action('woocommerce_after_product_attribute_settings', 'wcb_add_product_attribute_is_highlighted', 10, 2);
add_action('wp_ajax_woocommerce_save_attributes', 'wcb_ajax_woocommerce_save_attributes', 10);
function get_attribute_highlighted($id, $i) {
global $post;
$id = sanitize_title($id);
$id = strtolower($id);
$val = get_post_meta( $post->ID, "attribute_".$id."_highlighted_".$i, true);
return !empty($val) ? $val : false;
}
function wcb_add_product_attribute_is_highlighted($attribute, $i=0) {
$value = get_attribute_highlighted($attribute->get_name(), $i); ?>
<tr>
<td>
<div class="enable_highlighted">
<label><input type="hidden" name="attribute_highlighted[<?php echo esc_attr( $i ); ?>]" value="0" /><input type="checkbox" class="checkbox" <?php checked( $value, true ); ?> name="attribute_highlighted[<?php echo esc_attr( $i ); ?>]" value="1" /> <?php esc_html_e( 'Highlight attribute', $this->wcb ); ?></label>
</div>
</td>
</tr>
<?php
}
function wcb_ajax_woocommerce_save_attributes() {
check_ajax_referer( 'save-attributes', 'security' );
parse_str( $_POST['data'], $data );
$post_id = absint( $_POST['post_id'] );
if(array_key_exists("attribute_highlighted", $data) && is_array($data["attribute_highlighted"])) {
foreach($data["attribute_highlighted"] as $i => $val) {
$attr_name = sanitize_title($data["attribute_names"][$i]);
$attr_name = strtolower($attr_name);
update_post_meta( $post_id, "attribute_".$attr_name."_highlighted_".$i, wc_string_to_bool($val) );
}
}
}
In the end the only thing I had to add to my code was a hidden input with the same name as the checkbox but with a value of 0: <input type="hidden" name="attribute_highlighted[<?php echo esc_attr( $i ); ?>]" value="0" />
Here an image of the result (https://i.stack.imgur.com/VscT1.jpg). By clicking on save the value of the checkbox is maintained. The value is saved in a post_meta of the post that you are modifying. This is useful if you want to highlight a specific attribute in the front end.
I appreciate the help of #LoicTheAztec :)
As I struggled with the same issue I have tried using the code from Jesus Magallon. However, it did not work.
I found out that the priority of wp_ajax_woocommerce_save_attributes needed to be set to 0, otherwise the callback is not run for some reason.
Forthermore, if we only use $post->ID for get_post_meta() the correct results state of the checkbox will only be visible on page reload. To make sure the selected state is also visible direclty after ajax saving/reloading, we need to use $post_id = isset( $_POST['post_id'] ) ? absint( $_POST['post_id'] ) : $post->ID; instead.
Here the final version that should work perfectly for everyone:
add_action( 'woocommerce_after_product_attribute_settings', 'wcb_add_product_attribute_is_highlighted', 10, 2);
add_action( 'wp_ajax_woocommerce_save_attributes', 'wcb_ajax_woocommerce_save_attributes', 0);
function get_attribute_highlighted( $attribute_name, $i ) {
global $post;
// ID for either from ajax or from post
$post_id = isset( $_POST['post_id'] ) ? absint( $_POST['post_id'] ) : $post->ID ;
$attribute_name = strtolower( sanitize_title( $attribute_name ) );
$val = get_post_meta( $post_id, 'attribute_' . $attribute_name . '_highlighted_' . $i, true );
return !empty( $val ) ? $val : false;
}
function wcb_add_product_attribute_is_highlighted( $attribute, $i=0 ) {
$value = get_attribute_highlighted($attribute->get_name(), $i); ?>
<tr>
<td>
<div class="enable_highlighted">
<label>
<input type="hidden" name="attribute_highlighted[<?php echo esc_attr( $i ); ?>]" value="0" />
<input type="checkbox" class="checkbox" <?php checked( $value, true ); ?> name="attribute_highlighted[<?php echo esc_attr( $i ); ?>]" value="1" />
<?php esc_html_e( 'Highlight attribute', 'textdomain' ); ?>
</label>
</div>
</td>
</tr>
<?php
}
function wcb_ajax_woocommerce_save_attributes() {
check_ajax_referer( 'save-attributes', 'security' );
parse_str( $_POST['data'], $data );
$post_id = absint( $_POST['post_id'] );
if( array_key_exists( 'attribute_highlighted', $data ) && is_array( $data['attribute_highlighted'] ) ) {
foreach( $data['attribute_highlighted'] as $i => $val ) {
$attr_name = sanitize_title( $data['attribute_names'][$i] );
$attr_name = strtolower( $attr_name );
update_post_meta( $post_id, 'attribute_' . $attr_name . '_highlighted_' . absint( $i ), wc_string_to_bool( $val ) );
}
}
}
#ink almost got it, but it's not working when you click on Update button of whole product directly. You always need to click on Save attributes button firstly and that's wrong, because when you try other checkboxes then you'll see it works also on Update click.
So I would completely remove that add_action( 'wp_ajax_woocommerce_save_attributes', 'wcb_ajax_woocommerce_save_attributes', 0); and wcb_ajax_woocommerce_save_attributes function and use this instead:
add_filter( 'woocommerce_admin_meta_boxes_prepare_attribute', function( $attribute, $data, $i ){
global $post;
if( is_object( $post ) && isset( $post->ID ) ){
$post_id = $post->ID;
}else{
$post_id = absint( $_POST['post_id'] );
}
if( array_key_exists( 'attribute_highlighted', $data ) && is_array( $data['attribute_highlighted'] ) ){
foreach( $data['attribute_highlighted'] as $i => $value ){
$attr_name = sanitize_title( $data['attribute_names'][ $i ] );
update_post_meta( $post_id, 'attribute_' . $attr_name . '_highlighted_' . absint( $i ), wc_string_to_bool( $value ) );
}
}
return $attribute;
}, 10, 3 );
perfect code but change the hook
add_action('wp_ajax_woocommerce_save_attributes', 'wcb_ajax_woocommerce_save_attributes', 10);
to
add_action('wp_ajax_woocommerce_save_attributes', 'wcb_ajax_woocommerce_save_attributes', 0);
#Jesús Magallón's
Answer need little modifications.
Remove the function get_attribute_highlighted() and replace this line
$value = get_attribute_highlighted($attribute->get_name(), $i);
TO
global $post;
$post_id = isset($_POST['post_id']) ? absint($_POST['post_id']) : $post->ID ;
$value = get_post_meta($post_id , "attribute_description".$i, true);
It will show ajax saved value instance of empty;
And Change hooks
add_action('wp_ajax_woocommerce_save_attributes', 'wcb_ajax_woocommerce_save_attributes', 10);
TO
add_action('wp_ajax_woocommerce_save_attributes', 'wcb_ajax_woocommerce_save_attributes', 0);

Resources