有没有办法验证 Woocommerce 中是否存在产品的字段属性?

Is there a way to validade if a field attribute of a product exists in Woocommerce?

我找到了一个 youtube 教程,在 Wordpress 中创建一个插件,为每个产品添加一个输入字段,以便客户端可以上传图片。 您可以将此字段属性添加到产品或不添加

该代码具有验证功能,用于检查图片是否已上传。如果没有,则会提示您警告说您必须这样做。原始代码使 所有产品 的警告处于活动状态,即使是那些没有该字段的产品。

我更改了代码以检查产品是否具有该字段:

// custom input validation
function fp_field_validation($passed, $product_id, $quantity)
{
    $title = $_FILES['fp-file-field'];
    if (empty($_FILES['fp-file-field']["name"]) && isset($title)) {
        // Fails validation
        $passed = false;
        wc_add_notice(__('Por favor insira una imagen para su producto.', 'fp'), 'error');
    }
    return $passed;
}
add_filter('woocommerce_add_to_cart_validation', 'fp_field_validation', 10, 3);

这是完整的代码:

<?php

// Display the custom text field
function fp_create_field()
{
    $args = array(
        'id' => 'custom_file_field_title',
        'label' => __('Additional Field Title', 'fp'),
        'class' => 'fp-custom-field',
        'desc_tip' => true,
        'description' => __('Enter the title of your additional custom text field.', 'ctwc'),
    );
    woocommerce_wp_text_input($args);
}
add_action('woocommerce_product_options_general_product_data', 'fp_create_field');



// save data from custom field
function fp_save_field_data($post_id)
{
    $product = wc_get_product($post_id);
    $title = isset($_POST['custom_file_field_title']) ? $_POST['custom_file_field_title'] : '';
    $product->update_meta_data('custom_file_field_title', sanitize_text_field($title));
    $product->save();
}
add_action('woocommerce_process_product_meta', 'fp_save_field_data');


// Display field on the Product Page
function fp_display_field()
{
    global $post;
    // Check for the custom field value
    $product = wc_get_product($post->ID);
    $title = $product->get_meta('custom_file_field_title');
    if ($title) {
        // Display the field if not empty
        printf(
            '<div class="fp-custom-field-wrapper"><label for="fp-file-field" style="margin-right: 30px;">%s: </label><input type="file" id="fp-file-field" name="fp-file-field"></div><br /><hr />',
            esc_html($title)
        );
    }
}
add_action('woocommerce_before_add_to_cart_button', 'fp_display_field');


// custom input validation
function fp_field_validation($passed, $product_id, $quantity)
{
    $title = $_FILES['fp-file-field'];
    if (empty($_FILES['fp-file-field']["name"]) && isset($title)) {
        // Fails validation
        $passed = false;
        wc_add_notice(__('Por favor insira una imagen para su producto.', 'fp'), 'error');
    }
    return $passed;
}
add_filter('woocommerce_add_to_cart_validation', 'fp_field_validation', 10, 3);


// add field data to the cart
function fp_add_field_data_to_cart($cart_item_data, $product_id, $variation_id, $quantity)
{
    if (!empty($_FILES['fp-file-field']["name"])) {
        // WordPress environment
        require(dirname(__FILE__) . '/../../../wp-load.php');

        $wordpress_upload_dir = wp_upload_dir();
        // $wordpress_upload_dir['path'] is the full server path to wp-content/uploads/2017/05, for multisite works good as well
        // $wordpress_upload_dir['url'] the absolute URL to the same folder, actually we do not need it, just to show the link to file
        $i = 1; // number of tries when the file with the same name already exists

        $file_image = $_FILES['fp-file-field'];
        $new_file_path = $wordpress_upload_dir['path'] . '/' . $file_image['name'];
        $new_file_mime = mime_content_type($file_image['tmp_name']);

        if (empty($file_image))
            die('Archivo no seleccionado.');

        if ($file_image['error'])
            die($file_image['error']);

        if ($file_image['size'] > wp_max_upload_size())
            die('Imagen es demasiada grande.');

        if (!in_array($new_file_mime, get_allowed_mime_types()))
            die('Este tipo de archivo no es permitido.');

        while (file_exists($new_file_path)) {
            $i++;
            $new_file_path = $wordpress_upload_dir['path'] . '/' . $i . '_' . $file_image['name'];
        }

        // if everything is fine
        if (move_uploaded_file($file_image['tmp_name'], $new_file_path)) {
            $upload_id = wp_insert_attachment(array(
                'guid'           => $new_file_path,
                'post_mime_type' => $new_file_mime,
                'post_title'     => preg_replace('/\.[^.]+$/', '', $file_image['name']),
                'post_content'   => '',
                'post_status'    => 'inherit'
            ), $new_file_path);

            // wp_generate_attachment_metadata() won't work if you do not include this file
            require_once(ABSPATH . 'wp-admin/includes/image.php');

            // Generate and save the attachment metas into the database
            wp_update_attachment_metadata($upload_id, wp_generate_attachment_metadata($upload_id, $new_file_path));
        }
        // Add item data
        $cart_item_data['file_field'] = $wordpress_upload_dir['url'] . '/' . basename($new_file_path);
        $product = wc_get_product($product_id);
        $price = $product->get_price();
        $cart_item_data['total_price'] = $price;
    }
    return $cart_item_data;
}
add_filter('woocommerce_add_cart_item_data', 'fp_add_field_data_to_cart', 10, 4);


// update cart price
function fp_calculate_cart_totals($cart_obj)
{
    if (is_admin() && !defined('DOING_AJAX')) {
        return;
    }
    // Iterate through each cart item
    foreach ($cart_obj->get_cart() as $key => $value) {
        if (isset($value['total_price'])) {
            $price = $value['total_price'];
            $value['data']->set_price(($price));
        }
    }
}
add_action('woocommerce_before_calculate_totals', 'fp_calculate_cart_totals', 10, 1);


// display field in the cart
function fp_field_to_cart($name, $cart_item, $cart_item_key)
{
    if (isset($cart_item['file_field'])) {
        $name .= sprintf(
            '<p>%s</p>',
            esc_html($cart_item['file_field'])
        );
    }
    return $name;
}
add_filter('woocommerce_cart_item_name', 'fp_field_to_cart', 10, 3);


// Add custom field to order object
function fp_add_field_data_to_order($item, $cart_item_key, $values, $order)
{
    foreach ($item as $cart_item_key => $values) {
        if (isset($values['file_field'])) {
            $item->add_meta_data(__('Custom Field', 'fp'), $values['file_field'], true);
        }
    }
}
add_action('woocommerce_checkout_create_order_line_item', 'fp_add_field_data_to_order', 10, 4);![![enter image description here](https://i.stack.imgur.com/SX7Zs.jpg)](https://i.stack.imgur.com/8yzMh.jpg)

我在第 5 行添加了第 4 行和 && isset($title)

**问题:**当您转到单个产品页面并单击购买时,该代码有效。但是在一般页面中,当您点击添加到购物车时,它确实有效。它让输入字段的产品通过。

应该检查产品是否有字段属性,如果有提示消息添加图片,否则将产品添加到购物车,在所有页面,而不仅仅是单个产品页面。

我找到了解决办法!!这不是我要找的,而是一种解决方法。 现在,它不再添加到购物车,而是显示一个按钮,引导您进入验证工作的单个产品页面。我找到 this post here 和代码:

add_filter( 'woocommerce_loop_add_to_cart_link', 'replacing_add_to_cart_button', 10, 2 );

function replacing_add_to_cart_button( $button, $product  ) {
    $button_text = __("View product", "woocommerce");
    $button = '<a class="button" href="' . $product->get_permalink() . '">' . $button_text . '</a>';

    return $button;
}