How do I setup WooCommerce's product options to operate like Volusion's option system?

353 views Asked by At

We are migrating a Volusion website to WooCommerce. The administrator of that site loves the fact that add-ons are a separate entity, managed independently.

I'll try to explain how Volusion allows this through an example. For example, an option category could be: Engraving Sections

And the options would be

  • 1 (price difference $0)
  • 2 (price difference $8)

Another category would be: Add optional screws

And those options would be

  • Bronze screws ($0.20)
  • Nickel screws ($0.20)

Each option is assigned to a product on the edit screen by entering a product code. The "magic" that the admin likes about Volusion is that you can go into the option editor, and edit an option, and it applies for all of its related products. In this example, he could change Nickel Screws to be $0.30, and it would apply to 1000 products.

I tried to see how to do this in WooCommerce but got stuck. I am using add-ons to replace "options" in Volusion. The issue with that is that add-ons are either managed on a product by product basis, or if globally there isn’t much available as far as configuring what products those can be assigned to (besides categories which doesn't work in this situation).

How Volusion stores and manages Options is nothing like how any other e-commerce platform stores and manages Add-ons. And I'm stuck and don't know how to configure WooCommerce to handle add-ons in the way that Volusion handles Options. Please help. Thanks!

1

There are 1 answers

1
helgatheviking On

So I've managed to get something working in 3 parts.

  1. Show the global add-ons as a multi-select in the product data metabox on the Add-ons tab
  2. Save the custom meta field
  3. Add the global add-ons into the list of add-ons to display on the front-end

NB: I suggest creating a dummy product category. Assign the global addon to appear for products in the dummy category, that keeps them from displaying everywhere so they only appear when you add them to the metabox.

/**
 * Add a custom field to the Add-ons meta panel
 */
function kia_add_custom_addons_fields() {

    global $product_object;

    if( ! $product_object instanceof WC_Product )  {
        return;
    }

    $global_addons = WC_Product_Addons_Groups::get_all_global_groups();

    ?>
    <div class="wc-pao-field-header">
        <p><strong><?php esc_html_e( 'Global Add-on Groups', 'your-text-domain' ); ?><?php echo wc_help_tip( __( 'Add a global group to this particular product', 'your-text-domain' ) ); ?></strong></p>
    </div>

    <div class="wc-pao-global-addons">

        <p class="form-field">
            <label for="global_addons"><?php _e( 'Apply Global Add-ons to this product', 'your-text-domain' ); ?></label>

        <?php

        // Generate some data for the select2 input.
        $product_add_ons = array_filter( (array) $product_object->get_meta( '_global_addons' ) );

            ?>

            <select id="global_addons" class="wc-enhanced-select" name="global_addons[]" multiple="multiple" style="width: 400px;" data-sortable="sortable" data-placeholder="<?php esc_attr_e( 'Search for a Global Add-on&hellip;', 'your-text-domain' ); ?>" >
            <?php
                foreach ( $global_addons as $add_on ) {
                    echo '<option value="' . esc_attr( $add_on['id'] ) . '"' . selected( in_array( $add_on['id'], $product_add_ons ), true, false ) . '>' . wp_kses_post( $add_on['name'] ) . '</option>';

                }
            ?>
            </select>

        </p>
    </div>
<?php
}
add_action( 'woocommerce_product_addons_panel_start', 'kia_add_custom_addons_fields' );


/**
 * Save the custom field data.
 *
 * @param obj $product WC_Product - the product object.
 */
function kia_save_custom_addons_fields( $product ) {

    // Layout.
    if ( ! empty( $_POST[ 'global_addons' ] ) ) {

        $meta = array_map( 'intval', (array) $_POST[ 'global_addons' ] );

        $product->add_meta_data( '_global_addons', $meta, true );
    }

}
add_action( 'woocommerce_admin_process_product_object', 'kia_save_custom_addons_fields' );


/**
 * Force the custom add-on into the product display.
 *
 * @param  array $product_addons
 * @param  int $post_id
 * @param  return array 
 */
function kia_add_global_product_addons( $product_addons, $post_id ) {

    global $product;

    if( ! is_admin() && $product instanceof WC_Product && $post_id === $product->get_id() ) {


        $meta = $product->get_meta( '_global_addons', true );

        if( ! empty( $meta ) ) {

            $args = array(
                'posts_per_page'   => -1,
                'post_type'        => 'global_product_addon',
                'post_status'      => 'publish',
                'suppress_filters' => true,
                'include' => $meta
            );

            $global_addons = get_posts( $args );

            if ( $global_addons ) {
                $new_addons = array();
                foreach ( $global_addons as $global_addon ) {
                    $new_addon = apply_filters( 'get_product_addons_fields', array_filter( (array) get_post_meta( $global_addon->ID, '_product_addons', true ) ), $global_addon->ID );
                    $new_addons = $new_addons + $test;
                }

                $product_addons = array_merge( $new_addons, $product_addons );

            }

        }
    }

    return $product_addons;
}
add_filter( 'get_product_addons_fields', 'kia_add_global_product_addons', 10, 2 );