Daniel Immke

Handling advanced product imports in WooCommerce

Learn how to handle advanced things like core fees when importing products into WooCommerce.

I recently wrapped up a big WooCommerce project that required quite a bit of customization. I’ve decided to write about a few of those customizations and share code snippets. See a previous entry in the series here.

The Problem

I had a client with over 9,000 products for their WooCommerce store. That is a crazy amount of products on it’s face, but a lot of the products were connected to each other, and had specific attributes. This was all managed with a carefully curated spreadsheet. I needed a way to enable them to reliably import these products whenever they had new ones without having to manually go in and add them in the administration panel.

I searched around and found WP All Import. This powerful plugin handled a lot of the heavy lifting. It lets you upload a spreadsheet and map that spreadsheet to data in WordPress. Great! The only problem was, some of these products had attributes that couldn’t simply be mapped to things in WooCommerce.

Core Fees (The advanced part)

I’ll give an example. Some of the items designated as “products” in the spreadsheet were actually core fees. If you don’t know what a core fee is, Ebay gives a pretty good explanation. It’s common for people who manufacture expensive and specialized parts to require this. In the spreadsheet, the part that the fee was tied to was designated in a specific column.

I had installed another WooCommerce plugin called Force Sells that allowed two products to be tied together. This plugin worked well, but there was no way to map the data when importing with WP All Import to the Force Sells plugin. I needed a way to tie the data together programmatically, after the actual import had occurred.

The Solution: Functions and hooks

Luckily, WP All Import has several useful hooks in their plugin including pmxi_after_xml_import. This lets you run code after the import is complete.

When importing I was importing in the admin area, I designated rows in the spreadsheet that had a value in the “Core Fee” column to have a custom field named core_fee. Every product that had a core fee attached had the ID of that core fee stored in a custom field. Then, using the mxi_after_xml_import hook I built a function that would take all of these core fee items, hide them from public view and associate them with the correct product. This way, the only time a user saw the core fee was after they had added a product to their cart.

Here’s the code:

// Maps core part numbers to force sell after importing is finished.
add_action('pmxi_after_xml_import', 'danieldo_core_fees', 10, 1);

function danieldo_core_fees($post) {

    // Grab every product that was imported with a core fee
    $core_query = new WP_Query( array(
        'post_type' => 'product',
        'posts_per_page'   => -1,
        'meta_query' => array(
                'key'     => 'core_fee',
                'value'   => '',
                'compare' => '!=',
    ) );

    $products = $core_query->posts;

    foreach ($products as $product) {

        $core_id = get_post_meta($product->ID, 'core_fee', true);

        // Grab a post object by the core fee ID
        $core_fee = get_page_by_title( strval($core_id), OBJECT, 'product' );
        // Add the ID to a special custom field for the Force Sells plugin.
        add_post_meta($product->ID, '_force_sell_synced_ids', array($core_fee->ID), true);

        // Disable visibiity on core fees so they won't show up where they aren't supposed to by default.
        wp_set_object_terms( $core_fee->ID, array('exclude-from-catalog', 'exclude-from-search'), 'product_visibility', true );

        // Remove original custom field to keep things tidy
        delete_post_meta($product->ID, 'core_fee');

} ?>


This method worked reliably for several unusual things that didn’t fit within the normal parameters of importing products. And because of WP All Import’s easy to use interface and ability to save import templates, I was able to hand off this advanced importing system to my clients confident that they would be able to import whenever the need arose without having to involve me further. Hope you got something out of this!

Hey — My name is Daniel Immke. I’m a designer & developer currently building Pickwick.

If you liked my writing, check out more posts or subscribe.