在Woocommerce中为<variation>发布的值无效

时间:2017-10-02 12:53:04

标签: wordpress woocommerce

我尝试将产品的变化从选项更改为无线电输入。我复制了我的子主题并更新了文件variable.php。做了一些更改,但是当我尝试添加到购物车时,我有错误:

Invalid value posted for Size

这是Select版本中的HTML:

<select id="size" class="" name="attribute_size" data-attribute_name="attribute_size" data-show_option_none="yes">
    <option value="">Choose an option</option>
    <option value="15" class="attached enabled">15</option>
    <option value="15.5" class="attached enabled">15.5</option>
    <option value="16" class="attached enabled">16</option>
</select>

这是带有无线电输入的HTML:

<ul class="product-size">

    <li class="size">
        <div>
            <input style="display:none" type="radio" data-attribute-name="attribute_size" name="attribute_size" value="15" id="size_v_15">
            <label for="size_v_15">15</label>
        </div>
    </li>
    <li class="size">
        <div>
            <input style="display:none" type="radio" data-attribute-name="attribute_size" name="attribute_size" value="15.5" id="size_v_15.5" checked="checked">
            <label for="size_v_15.5">15.5</label>
        </div>
    </li>
    <li class="size">
        <div>
            <input style="display:none" type="radio" data-attribute-name="attribute_size" name="attribute_size" value="16" id="size_v_16">
            <label for="size_v_16">16</label>
        </div>
    </li>
</ul>

如您所见,这两个版本中namevalue都相同。但是,我得到了上述错误。如果你需要我在variable.php文件中更改的代码,这里是:

<?php

function print_attribute_radio($checked_value, $value, $label, $name)
{
    $checked = sanitize_title($checked_value) === $checked_value ? checked($checked_value, sanitize_title($value) , false) : checked($checked_value, $value, false);
    $input_name = 'attribute_' . esc_attr($name);
    $esc_value = esc_attr($value);
    $id = esc_attr($name . '_v_' . $value);
    $filtered_label = apply_filters('woocommerce_variation_option_name', $label);
    printf('<div><input style="display:none" type="radio" data-attribute-name="%1$s" name="%1$s" value="%2$s" id="%3$s" %4$s><label for="%3$s">%5$s</label></div>', $input_name, $esc_value, $id, $checked, $filtered_label);
}


if (sanitize_title($attribute_name) == 'size'):
    $sanitized_name = sanitize_title($attribute_name);
    if (isset($_REQUEST['attribute_' . $sanitized_name])) {
        $checked_value = $_REQUEST['attribute_' . $sanitized_name];
    }
    elseif (isset($selected_attributes[$sanitized_name])) {
        $checked_value = $selected_attributes[$sanitized_name];
    }
    else {
        $checked_value = '';
    }

?>
<h3>Choose Your Size</h3>
<ul class="product-size">

<?php
    foreach($options as $option) {
        echo '<li class="size">';
        print_attribute_radio($checked_value, $option, $option, $sanitized_name);
        echo '</li>';
    } ?>
    </ul>
    <script type="text/javascript">
                         jQuery('.product-size > li').click(function(e) {
                            jQuery('.product-size > li').removeClass('size-selected');
                            jQuery(this).addClass('size-selected');
                         var option_id = jQuery(this).find("input").attr("checked",true);
                         });
   </script>
<?php endif; ?>

1 个答案:

答案 0 :(得分:0)

我将您的代码添加到标准的woocommerce模板variable.php中 这里的主要目标是获取请求参数,woocommece标准选择给vary_form,并用隐藏输入中的自定义参数替换它。 这是一个肮脏的伎俩,因为一些标准的woocommerce行为将不起作用,你需要更多的代码来返回它,但你已经可以正确地将产品添加到你的购物车。

if ( ! defined( 'ABSPATH' ) ) {
exit;
}

global $product;
// get arr as varition id - value and vaiation attr name - key
$product_variations_arr = $product->get_available_variations();
$varitions_id_value_arr = [];
foreach ($product_variations_arr as $variation_arr) {
    $varitions_id_value_arr[ current( $variation_arr['attributes'] ) ] = $variation_arr['variation_id'];
}

$attribute_keys = array_keys( $attributes );

do_action( 'woocommerce_before_add_to_cart_form' ); ?>

<?php

function print_attribute_radio($checked_value, $value, $label, $name, $varitions_id_value_arr)
{
    $checked = sanitize_title($checked_value) === $checked_value ? checked($checked_value, sanitize_title($value) , false) : checked($checked_value, $value, false);
    $input_name = 'attribute_' . esc_attr($name);
    $esc_value = esc_attr($value);
    $id = esc_attr($name . '_v_' . $value);
    $filtered_label = apply_filters('woocommerce_variation_option_name', $label);
    printf('<div><input type="radio" data-variation-id="%6$s" data-attribute-name="%1$s" name="%1$s" value="%2$s" id="%3$s" %4$s><label for="%3$s">%5$s</label></div>', $input_name, $esc_value, $id, $checked, $filtered_label, $varitions_id_value_arr[$value]);
}


?>
<form class="variations_form cart" method="post" enctype='multipart/form-data' data-product_id="<?php echo absint( $product->get_id() ); ?>" data-product_variations="<?php echo htmlspecialchars( wp_json_encode( $available_variations ) ) ?>">
    <?php do_action( 'woocommerce_before_variations_form' ); ?>

    <?php if ( empty( $available_variations ) && false !== $available_variations ) : ?>
        <p class="stock out-of-stock"><?php _e( 'This product is currently out of stock and unavailable.', 'woocommerce' ); ?></p>
    <?php else : ?>
    <?php foreach ( $attributes as $attribute_name => $options ) : 

        if (sanitize_title($attribute_name) == 'pa_test'):
            $sanitized_name = sanitize_title($attribute_name);
            if (isset($_REQUEST['attribute_' . $sanitized_name])) {
                $checked_value = $_REQUEST['attribute_' . $sanitized_name];
            }
            elseif (isset($selected_attributes[$sanitized_name])) {
                $checked_value = $selected_attributes[$sanitized_name];
            }
            else {
                $checked_value = '';
            }

            ?>
            <h3>Choose Your Size</h3>
            <ul class="product-size">
                <?php
                    foreach($options as $option) {
                        echo '<li class="size">';
                        print_attribute_radio($checked_value, $option, $option, $sanitized_name, $varitions_id_value_arr);
                        echo '</li>';
                    }
                ?>
            </ul>

            <input type="hidden" name="attribute_pa_test" value="">

            <script type="text/javascript">
                jQuery('.product-size > li').click(function(e) {
                    jQuery('.product-size > li').removeClass('size-selected');
                    jQuery(this).addClass('size-selected');
                    var option_id = jQuery(this).find("input").attr("checked", true);

                    var variation_value = jQuery(this).find("input").attr("checked", true).val();
                    var variation_id = jQuery(this).find("input").attr("checked", true).attr('data-variation-id')

                    // set choosen variation in hiden inputs
                    jQuery('input[name=variation_id]').val( variation_id );
                    jQuery('input[name=attribute_pa_test]').val( variation_value );
                 });
            </script>
        <?php endif; ?>
        <table class="variations" cellspacing="0">
            <tbody>

                    <tr>
                        <td class="label"><label for="<?php echo sanitize_title( $attribute_name ); ?>"><?php echo wc_attribute_label( $attribute_name ); ?></label></td>
                        <td class="value">
                            <?php
                                //$selected = isset( $_REQUEST[ 'attribute_' . sanitize_title( $attribute_name ) ] ) ? wc_clean( stripslashes( urldecode( $_REQUEST[ 'attribute_' . sanitize_title( $attribute_name ) ] ) ) ) : $product->get_variation_default_attribute( $attribute_name );
                                //wc_dropdown_variation_attribute_options( array( 'options' => $options, 'attribute' => $attribute_name, 'product' => $product, 'selected' => $selected ) );
                                //echo end( $attribute_keys ) === $attribute_name ? apply_filters( 'woocommerce_reset_variations_link', '<a class="reset_variations" href="#">' . esc_html__( 'Clear', 'woocommerce' ) . '</a>' ) : '';
                            ?>
                        </td>
                    </tr>
                <?php endforeach;?>
            </tbody>
        </table>

        <?php do_action( 'woocommerce_before_add_to_cart_button' ); ?>

        <div class="single_variation_wrap">
            <?php
                /**
                 * woocommerce_before_single_variation Hook.
                 */
                do_action( 'woocommerce_before_single_variation' );

                /**
                 * woocommerce_single_variation hook. Used to output the cart button and placeholder for variation data.
                 * @since 2.4.0
                 * @hooked woocommerce_single_variation - 10 Empty div for variation data.
                 * @hooked woocommerce_single_variation_add_to_cart_button - 20 Qty and cart button.
                 */
                do_action( 'woocommerce_single_variation' );

                /**
                 * woocommerce_after_single_variation Hook.
                 */
                do_action( 'woocommerce_after_single_variation' );
            ?>
        </div>

        <?php do_action( 'woocommerce_after_add_to_cart_button' ); ?>
    <?php endif; ?>

    <?php do_action( 'woocommerce_after_variations_form' ); ?>
</form>

<?php
do_action( 'woocommerce_after_add_to_cart_form' );