如何在Woocommerce中保存属性的自定义字段?

时间:2018-09-11 19:54:28

标签: wordpress woocommerce

我试图在Woocommerce的产品属性中创建一个自定义字段。这可以选择是否突出显示属性。例如:

https://i.stack.imgur.com/Ge76B.png

我想要做的是我在后端指定为突出显示的字段以某种方式显示在前端。

到目前为止,我已经能够添加该字段,但是我还没有弄清楚如何保存它。这就是我所拥有的:

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]) );
    }
}

我使用woocommerce_admin_meta_boxes_prepare_attribute类的offsetSetoffsetGet方法尝试了WC_Product_Attribute过滤器,但是我不明白它是如何工作的。我无法使其保存我的自定义值。

欢迎您的帮助,谢谢。


升级

我通过woocommerce_admin_meta_boxes_prepare_attribute操作更改了wp_ajax_woocommerce_save_attributes过滤器,它似乎可以工作。现在我遇到的问题是,第一次保存后它不会更新。

我解释了当前的问题:我有一个复选框,单击该复选框时,它会被激活,保存并在重新加载状态时保持不变。如果现在我要停用它,则在保存状态后,它不会保留为禁用状态,而是恢复为激活状态。

这是更新的代码:

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) );
        }
    }
}

4 个答案:

答案 0 :(得分:1)

@Jesús Magallón's

答案几乎不需要修改。 删除功能get_attribute_highlighted()并替换此行

   $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);

它将显示ajax保存值实例为空;

然后换钩子

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

答案 1 :(得分:1)

当我遇到同样的问题时,我尝试使用 Jesus Magallon 的代码。但是,它不起作用。

我发现wp_ajax_woocommerce_save_attributes的优先级需要设置为0,否则回调不运行。

此外,如果我们只对 $post->ID 使用 get_post_meta(),则复选框的正确结果状态将仅在页面重新加载时可见。为了确保选定状态在 ajax 保存/重新加载后也是可见的,我们需要改用 $post_id = isset( $_POST['post_id'] ) ? absint( $_POST['post_id'] ) : $post->ID;

这里是适合所有人的最终版本:

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 ) );
        }
    }
}

答案 2 :(得分:0)

我找到了解决我问题的方法。我共享代码,以防有人有用。问候!

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) );
        }
    }
}

最后,我唯一需要添加到代码中的是与复选框名称相同但值为0的隐藏输入:<input type="hidden" name="attribute_highlighted[<?php echo esc_attr( $i ); ?>]" value="0" />

这里是结果的图像(https://i.stack.imgur.com/VscT1.jpg)。通过单击保存,将保持复选框的值。该值保存在您要修改的帖子的post_meta中。如果要突出显示前端中的特定属性,这很有用。

我感谢@LoicTheAztec的帮助:)

答案 3 :(得分:0)

完美的代码,但更改了钩子

add_action('wp_ajax_woocommerce_save_attributes', 'wcb_ajax_woocommerce_save_attributes', 10);

add_action('wp_ajax_woocommerce_save_attributes', 'wcb_ajax_woocommerce_save_attributes', 0);