Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Add a custom taxonomy to WooCommerce import/export
<?php
/*
* Plugin Name: WooCommerce Add Taxonomy to Export
* Plugin URI: https://gist.github.com/helgatheviking/114c8df50cabb7119b3c895b1d854533/
* Description: Add a custom taxonomy to WooCommerce import/export.
* Version: 1.0.1
* Author: Kathy Darling
* Author URI: https://kathyisawesome.com/
*
* Woo: 18716:fbca839929aaddc78797a5b511c14da9
*
* Text Domain: woocommerce-product-bundles
* Domain Path: /languages/
*
* Requires at least: 5.0
* Tested up to: 5.0
*
* WC requires at least: 3.5
* WC tested up to: 3.5.4
*
* Copyright: © 2017-2019 SomewhereWarm SMPC.
* License: GNU General Public License v3.0
* License URI: http://www.gnu.org/licenses/gpl-3.0.html
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Add CSV columns for exporting extra data.
*
* @param array $columns
* @return array $columns
*/
function kia_add_columns( $columns ) {
$columns[ 'custom_taxonomy' ] = __( 'Your taxonomy', 'your-text-domain' );
return $columns;
}
add_filter( 'woocommerce_product_export_column_names', 'kia_add_columns' );
add_filter( 'woocommerce_product_export_product_default_columns', 'kia_add_columns' );
/**
* MnM contents data column content.
*
* @param mixed $value
* @param WC_Product $product
* @return mixed $value
*/
function kia_export_taxonomy( $value, $product ) {
$terms = get_terms( array( 'object_ids' => $product->get_ID(), 'taxonomy' => 'your-taxonomy-slug' ) );
if ( ! is_wp_error( $terms ) ) {
$data = array();
foreach ( (array) $terms as $term ) {
$data[] = $term->term_id;
}
$value = json_encode( $data );
}
return $value;
}
add_filter( 'woocommerce_product_export_product_column_custom_taxonomy', 'kia_export_taxonomy', 10, 2 );
/**
* Import
*/
/**
* Register the 'Custom Column' column in the importer.
*
* @param array $columns
* @return array $columns
*/
function kia_map_columns( $columns ) {
$columns[ 'custom_taxonomy' ] = __( 'Your taxonomy', 'your-text-domain' );
return $columns;
}
add_filter( 'woocommerce_csv_product_import_mapping_options', 'kia_map_columns' );
/**
* Add automatic mapping support for custom columns.
*
* @param array $columns
* @return array $columns
*/
function kia_add_columns_to_mapping_screen( $columns ) {
$columns[ __( 'Your taxonomy', 'your-text-domain' ) ] = 'custom_taxonomy';
// Always add English mappings.
$columns[ 'Your taxonomy' ] = 'custom_taxonomy';
return $columns;
}
add_filter( 'woocommerce_csv_product_import_mapping_default_columns', 'kia_add_columns_to_mapping_screen' );
/**
* Decode data items and parse JSON IDs.
*
* @param array $parsed_data
* @param WC_Product_CSV_Importer $importer
* @return array
*/
function kia_parse_taxonomy_json( $parsed_data, $importer ) {
if ( ! empty( $parsed_data[ 'custom_taxonomy' ] ) ) {
$data = json_decode( $parsed_data[ 'custom_taxonomy' ], true );
unset( $parsed_data[ 'custom_taxonomy' ] );
if ( is_array( $data ) ) {
$parsed_data[ 'custom_taxonomy' ] = array();
foreach ( $data as $term_id ) {
$parsed_data[ 'custom_taxonomy' ][] = $term_id;
}
}
}
return $parsed_data;
}
add_filter( 'woocommerce_product_importer_parsed_data', 'kia_parse_taxonomy_json', 10, 2 );
/**
* Set taxonomy.
*
* @param array $parsed_data
* @return array
*/
function kia_set_taxonomy( $product, $data ) {
if ( is_a( $product, 'WC_Product' ) ) {
if( ! empty( $data[ 'custom_taxonomy' ] ) ) {
wp_set_object_terms( $product->get_id(), (array) $data[ 'custom_taxonomy' ], 'your-taxonomy-slug' );
}
}
return $product;
}
add_filter( 'woocommerce_product_import_inserted_product_object', 'kia_set_taxonomy', 10, 2 );
@webgmclassics

This comment has been minimized.

Copy link

@webgmclassics webgmclassics commented Apr 2, 2018

Typo in line 65: $columns should be $options

@webgmclassics

This comment has been minimized.

Copy link

@webgmclassics webgmclassics commented Apr 2, 2018

Typo: in line 130: should be $product->get_id();

@MrkKr

This comment has been minimized.

Copy link

@MrkKr MrkKr commented Aug 24, 2018

line 40: $data[] = $term->name; -> if you prefer Name instead ID to print in CSV cell
line 43: $data[] = $value = str_replace(array('["','"]'), '', json_encode( $data ) ); -> this trick removes [""] form CSV cell
lines 96-115: $parsed_data[ 'Taxonomy Name" ] -> you should remember, that is this place value is the name of Column, not taxonomy slug!

@malavikaprav

This comment has been minimized.

Copy link

@malavikaprav malavikaprav commented Jan 5, 2019

This is really a very useful code. Thank you all so much. I was able to get the export work but somehow I am not been able to get the import. Should the Import CSV contain term slug or term id? Tried both but not working. I have added my code here, any help is much appreciated. Here shop_section is the name of my custom taxonomy.

/**
 * Import shop section of the products from the CSV file
 */

/**
 * Register the 'Custom Column' column in the importer.
 *
 * @param  array  $options
 * @return array  $options
 */
function kia_map_columns( $options ) {
	$options[ 'custom_taxonomy' ] = __( 'Shop Section', 'your-text-domain' );
	return $options;
}
add_filter( 'woocommerce_csv_product_import_mapping_options', 'kia_map_columns' );

/**
 * Add automatic mapping support for custom columns.
 *
 * @param  array  $columns
 * @return array  $columns
 */
function kia_add_columns_to_mapping_screen( $columns ) {

	$columns[ __( 'Shop Section', 'your-text-domain' ) ] 	= 'custom_taxonomy';

	// Always add English mappings.
	$columns[ 'Shop Section' ]	= 'custom_taxonomy';

	return $columns;
}
add_filter( 'woocommerce_csv_product_import_mapping_default_columns', 'kia_add_columns_to_mapping_screen' );

/**
 * Decode data items and parse JSON IDs.
 *
 * @param  array                    $parsed_data
 * @param  WC_Product_CSV_Importer  $importer
 * @return array
 */
function kia_parse_taxonomy_json( $parsed_data, $importer ) {

	if ( ! empty( $parsed_data[ 'custom_taxonomy' ] ) ) {

		$data = json_decode( $parsed_data[ 'custom_taxonomy' ], true );

		unset( $parsed_data[ 'custom_taxonomy' ] );

		if ( is_array( $data ) ) {

			$parsed_data[ 'custom_taxonomy' ] = array();

			foreach ( $data as $term_id ) {
				$parsed_data[ 'custom_taxonomy' ][] = $term_id;
			}
		}
	}

	return $parsed_data;
}
add_filter( 'woocommerce_product_importer_parsed_data', 'kia_parse_taxonomy_json', 10, 2 );

/**
 * Set taxonomy.
 *
 * @param  array  $parsed_data
 * @return array
 */
function kia_set_taxonomy( $product, $data ) {

	if ( is_a( $product, 'WC_Product' ) ) {

		if( ! empty( $data [ 'custom_taxonomy' ] ) ) {
			wp_set_object_terms( $product->get_id(),  (array) $data ['custom_taxonomy'], 'shop_section' );
		}

	}

	return $product;
}
add_filter( 'woocommerce_product_import_inserted_product_object', 'kia_set_taxonomy', 10, 2 );
@rbsmidt

This comment has been minimized.

Copy link

@rbsmidt rbsmidt commented Aug 12, 2019

I too had issues getting the import of custom tax terms working as @malavikaprav. Figured out that the $product doesn't have an ID yet when woocommerce_product_import_pre_insert_product_object action is triggered. If anyone else is fiddling with this issue i solved it by adding $product->save() and wp_set_object_terms() afterwards.

@Red-N-Dusty

This comment has been minimized.

Copy link

@Red-N-Dusty Red-N-Dusty commented Aug 19, 2019

@rbsmidt, would you be willing to add your code to this thread? I'm either doing something goofy or I'm missing a step.

@rbsmidt

This comment has been minimized.

Copy link

@rbsmidt rbsmidt commented Aug 20, 2019

@Red-N-Dusty sure thing

The trick that worked for me was to do a save on the WC_Product object before adding the term through wp_set_object_terms. For clarification my custom taxonomy is called "collections", and in the CSV file i add the actual name of the collection (not the slug), which is used to fetch the term with get_term_by-helper function.
Hope it helps! My function below:

function process_import($object, $data) {
    if (is_a($object, 'WC_Product')) {
        if (!empty($data['collections'])) {
            // Save object to assign correct product id
            $object->save();
            $collection = get_term_by('name', $data['collections'], 'collections');
	    if ($collection) {
		wp_set_object_terms($object->get_id(), $collection->term_id, 'collections');
	    }
        }
    }
    return $object;
}
add_filter( 'woocommerce_product_import_pre_insert_product_object', 'process_import', 10, 2 );
@Red-N-Dusty

This comment has been minimized.

Copy link

@Red-N-Dusty Red-N-Dusty commented Aug 21, 2019

Thanks, @rbsmidt. After messing around with it for a few hours, I got it all to work as you described. At first, it was dropping long strings of terms separated by commas (ie. "foo1, bar1, foo2, bar2") into the taxonomy post. I resolved that by building an array and passing it to wp_set_object_terms().

I'll include my code but its pretty duplicitous between the pre_insert and insert filters. Maybe someone else has a better answer. Unfortunately, I'll have to come back to this later but for some reason, one won't work without the other.


function process_import($object, $data) {
    if (is_a($object, 'WC_Product')) {
        if (!empty($data['Part Number'])) {
            // Save object to assign correct product id
            $object->save();
			$terms = array();
			$part_numbers = $data['Part Number'];
			$part_numbers = explode(",",$part_numbers);
			
			foreach($part_numbers as $part_number){
				$part_number = get_term_by('name', $part_number, 'Part Number');
				$terms[]=$part_number->term_id;
			}
			
            
            if ($part_number) {
                wp_set_object_terms($object->get_id(), $terms, 'part_number');
            }
        }
    }
    return $object;
}
add_filter( 'woocommerce_product_import_pre_insert_product_object', 'process_import', 10, 2 );

/**
 * Set taxonomy.
 *
 * @param  array  $parsed_data
 * @return array
 */
function kia_set_taxonomy( $product, $data ) {

	if ( is_a( $product, 'WC_Product' ) ) {

		if( ! empty( $data[ 'part_number' ] ) ) {
			$terms = array();
			$part_numbers = $data['part_number'];
			if(strpos($part_numbers, ",")){
				$part_numbers = explode(",",$part_numbers);
				foreach($part_numbers as $part_number){
					$part_number = get_term_by('name', $part_number, 'part_number');
					$terms[] = $part_number->term_id;
				}
				wp_set_object_terms( $product->get_id(),  $terms, 'part_number' );
			}else{
				wp_set_object_terms( $product->get_id(),  (array) $part_numbers, 'part_number' );
			}
		}

	}

	return $product;
}
add_filter( 'woocommerce_product_import_inserted_product_object', 'kia_set_taxonomy', 10, 2 );

@Red-N-Dusty

This comment has been minimized.

Copy link

@Red-N-Dusty Red-N-Dusty commented Aug 21, 2019

@rbsmidt, I had a feeling that was wrong. I managed to get those previous functions to work once and that was only because I had already imported the terms using a different plugin while trying to find the answer to this problem. In the process of troubleshooting my error, I was able to combine the two functions. This is what I've come up with and I've put it through its paces already.


/**
 * Set taxonomy.
 *
 * @param  array  $parsed_data
 * @return array
 */

function kia_set_taxonomy( $product, $data ) {
	if ( is_a( $product, 'WC_Product' ) ) {
		if( ! empty( $data[ 'part_number' ] ) ) {
            		$product->save();
            		$part_numbers = $data[ 'part_number' ];
            		$part_numbers = explode(",", $part_numbers);
            		$terms = array();
            		foreach($part_numbers as $part_number){
                		if(!get_term_by('name', $part_number, 'part_number')){
                    			$partNumArgs= array(
                        			'cat_name' => $part_number,
                        			'taxonomy' => 'part_number',
                    			);
                    			$part_number_cat = wp_insert_category($partNumArgs);
                    			array_push($terms, $part_number_cat);
                		}else{
                    			$part_number_cat = get_term_by('name', $part_number, 'part_number')->term_id;
                    			array_push($terms, $part_number_cat);
                		}
            		}
			wp_set_object_terms( $product->get_id(),  $terms, 'part_number' );
		}
	}
	return $product;
}
add_filter( 'woocommerce_product_import_inserted_product_object', 'kia_set_taxonomy', 10, 2 );

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment