Skip to content
Advertisement

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

I found a youtube tutorial to create a plugin in WordPress to add an input field for each product, so that the client could upload an image. You can add this field attribute to a product or not.

The code has a validation function, to check if the image was uploaded or not. If not, promps you a warning saying that you have to. The original code makes the warning active for all products, even those that don’t have the field.

I changed the code to check if the product has the field or not:

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

This is the whole code:

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

I added line 4 and && isset($title) on line 5.

**The problem: **The code works when you go to the individual product page and click to buy it. But in the general page when you click to add to cart, it does work. It let the products with the input field pass.

It should check if the product has the field attribute, if it has prompt a message to add an image, otherwise add the product to the cart, in all pages, not just the individual product page.

Advertisement

Answer

I found a solution!! Is not what I was looking for, but is a workaround. Now instead of adding to the cart, it displays a button that leads you to the individual product page, where the validation works. I found this post here and the code:

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;
}
User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement