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

后端 未结 4 1847
野趣味
野趣味 2021-01-26 07:21

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:

相关标签:
4条回答
  • 2021-01-26 07:37

    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 :)

    0 讨论(0)
  • 2021-01-26 07:42

    @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);
    
    0 讨论(0)
  • 2021-01-26 07:45

    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);
    
    0 讨论(0)
  • 2021-01-26 07:51

    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 ) );
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题