skip to Main Content

Using WordPress + WooCommerce I’m offering a type of product that can be customized using a HTML canvas by moving some elements in the canvas.

When the user is happy with the customization and adds the customized product to the cart, I want to display de product image as the user customization.

In order to do so, I’ve been using the function canvas.toDataURL in order to send the base64 image of the canvas to the cart so I could display it on the cart page:

let cartData = new FormData();
cartData.append("action", "add_composition_to_cart");
cartData.append("composition_image", canvas.toDataURL("webp"));

axios.post(wc_add_to_cart_params.ajax_url, cartData);

And then, on the server:

function add_composition_to_cart() {
    $product_id = intval(get_option("customizable_product_id"));
    $quantity = 1;
    
    $composition = $_POST["composition"];

    $custom_cart_item = [
        "composition_image" => $composition_image,
    ];

    WC()->cart->add_to_cart($product_id, $quantity, 0, [], [ "custom_cart_item" => $custom_cart_item ]);

    wp_die();
}

add_action("wp_ajax_add_composition_to_cart", "add_composition_to_cart");
add_action("wp_ajax_nopriv_add_composition_to_cart", "add_composition_to_cart");

function cart_set_composition_image($_product_img, $cart_item, $cart_item_key) {
    if (isset($cart_item["custom_cart_item"]) && isset($cart_item["custom_cart_item"]["composition_image"])) {
        return '<img src="' . $cart_item["custom_cart_item"]["composition_image"] . '" />';
    }
    
    return $_product_img;
}

add_filter("woocommerce_cart_item_thumbnail", "cart_set_composition_image", 10, 3);

This works fine sometimes. The issue comes when the canvas is a bit larger as the base64 image string that is generated by canvas.toDataURL is very large and it can’t be stored in the WordPress MySQL database due to it exceeds the byte limit for one insert.

What would be a way to consistently achieve this?

I’ve thought I could re-generate the composition on the cart page, and then just run canvas.toDataURL on the browser client side in order generate the image without needing to save it in my database. But I’m not sure if I can add a shortcode on the cart page. Is that possible?

If not, can I store a temporary image attached to an item of the cart? How would be the proper way to do that?

2

Answers


  1. You could save the image into a file and store the file name or path in the database instead of the image itself. This would never run into size limits of MySQL and would be reliable. Yet, you have several things to implement in order to make this work:

    1. When the record is saved (insert or update), then a file needs to be created, besides the record being created, make sure the filename is unique
    2. When the record is updated or deleted, the old file needs to be removed
    3. Whenever you load the image, you need to load (and maybe cache) the image, because the filename is meaningless when you need to display the image

    If all these are resolved, then you will not run into MySQL limitations.

    Login or Signup to reply.
  2. Per request – assuming I’m understanding correctly. Also, it’s quite possible that your theme may provide other options, or be missing one or more of the hooks that appear in the default Woocommerce template.

    See https://www.businessbloomer.com/woocommerce-visual-hook-guide-cart-page/

    add_action( 'woocommerce_before_cart_table', 'so_add_shortcode_before_cart_table' ) ;
    function so_add_shortcode_before_cart_table() {
    
        echo do_shortcode( '[my-shortcode]' ) ;
    
    }
    

    If you need a dynamic variable, you can feed it in as a shortcode attribute, but, in most cases, if you’re coding the shortcode yourself, whether or not you need a dynamic variable, you might as well write a simple function that achieves the same thing.

    add_action( 'woocommerce_before_cart_table', 'so_add_some_stuff' ) ;
    function so_add_some_stuff() {
    
        //etc.
    
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search