Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
WordPress: Woocommerce Product Attributes - Bulk Modifier ( from custom to taxonomy attributes)
<?php
/**
* Plugin Name: Product Attributes - Bulk Modifier
* Description: Bulk update 'custom product attributes' to 'taxonomy product attributes'. Supports the GET variables, like: wpq_mode=run&wpq_from=colour&wpq_to=pa_colour&wpq_ppp=10&wpq_offset=0&wpq_post_type=product&wpq_post_status=any. WARNING: Backup DB first!!!
* Plugin Author: birgire
* Plugin URI: https://gist.github.com/birgire/0ed300ae4436fcaf508c
* Version: 0.0.2
*/
/**
* Example:
* To change all custom product attributes "colour" to "pa_colour" products taxonomy, we can run:
*
* http://example.tld/?wpq_mode=run&wpq_from=colour&wpq_to=pa_colour&wpq_ppp=100&wpq_offset=0&wpq_post_type=product&wpq_post_status=any
*
* WARNING: Remember to backup your database first!!!
*/
add_action( 'template_redirect', function()
{
// Activate product attribute modification (only available for admins):
if( current_user_can( 'manage_options' ) && 'run' === filter_input( INPUT_GET, 'wpq_mode' ) )
{
// Setup:
$meta_key = '_product_attributes';
// User input:
$from = filter_input( INPUT_GET, 'wpq_from', FILTER_SANITIZE_STRING );
$to = filter_input( INPUT_GET, 'wpq_to', FILTER_SANITIZE_STRING );
$post_type = filter_input( INPUT_GET, 'wpq_post_type', FILTER_SANITIZE_STRING );
$post_status = filter_input( INPUT_GET, 'wpq_post_status', FILTER_SANITIZE_STRING );
$ppp = filter_input( INPUT_GET, 'wpq_ppp', FILTER_SANITIZE_NUMBER_INT );
$offset = filter_input( INPUT_GET, 'wpq_offset', FILTER_SANITIZE_NUMBER_INT );
// Default values:
if( empty( $ppp ) )
{
$ppp = 10;
}
if( empty( $offset ) )
{
$offset = 0;
}
if( empty( $post_type ) )
{
$post_type = 'product';
}
if( empty( $post_status ) )
{
$post_status = 'any';
}
if( empty( $from ) || empty( $to ) )
{
wp_die( 'Oh, rembember that the "from" and "to" variable must be set!');
}
// Fetch products with product attributes:
$args = array(
'post_type' => sanitize_key( $post_type ),
'fields' => 'ids',
'posts_per_page' => (int) $ppp,
'offset' => (int) $offset,
'meta_key' => $meta_key,
'post_status' => sanitize_key( $post_status ),
);
$post_ids = get_posts( $args );
foreach( (array) $post_ids as $post_id )
{
$meta = get_post_meta( $post_id, $meta_key, true );
$product_needs_update = false;
foreach( (array) $meta as $key => $terms )
{
// Locate our meta attribute:
if( $from === $terms['name'] )
{
$product_needs_update = true;
$tmp = explode( '|', $terms['value'] );
$product_terms = array();
foreach( (array) $tmp as $term )
{
$product_terms[] = sanitize_key( $term );
}
// Remove the product meta attribute:
unset( $meta[$from] );
// Add it again as product taxonomy attribute:
$meta["{$to}"] = array(
'name' => "{$to}",
'value' => '',
'position' => $terms['position'],
'is_visible' => $terms['is_visible'],
'is_variation' => $terms['is_variation'],
'is_taxonomy' => 1,
);
} // end if
} // end foreach
if( $product_needs_update )
{
// Assign terms to the post (create them if they don't exists)
$term_taxonomy_ids = wp_set_object_terms( $post_id, $product_terms, $to, false );
if ( is_wp_error( $term_taxonomy_ids ) )
{
printf( "There was an error somewhere and the terms couldn't be set for post_id: %d <hr/>", $post_id );
}
else
{
update_post_meta( $post_id, $meta_key, $meta );
printf( "Success! The taxonomy post attributes were set for post_id: %d <hr/>", $post_id );
} // end if
} // end if current post needs update
} // end foreach post
die( 'Done!');
} // end if "run" action
});
@hornmedia

This comment has been minimized.

Copy link

@hornmedia hornmedia commented Nov 20, 2017

How can i start this plugin ?? :)

@digitalka

This comment has been minimized.

Copy link

@digitalka digitalka commented Jul 25, 2018

Dude I love you. You saved me HUGE amount of work

@lommaker

This comment has been minimized.

Copy link

@lommaker lommaker commented Mar 7, 2019

How can i start this plugin??

@valiermedia

This comment has been minimized.

Copy link

@valiermedia valiermedia commented Apr 18, 2019

For those of you who are asking how to start this plugin:

  1. Place the PHP file in a folder named woo-product-attributes-bulk-modifier. It needs to be in the directory root, not in a subfolder.
  2. Either FTP that folder to your plugins directory, or zip the file and go to "Add Plugin" and then upload the zip file via WP
  3. Activate the plugin
  4. Ensure that the product attribute has already been created, this plugin will migrate custom attributes to an EXISTING product attribute. If it hasn't been created, create it.
  5. Visit the following URL (swapping out the variables as needed - variables are in all caps): http://WWW.YOURSITE.COM/?wpq_mode=run&wpq_from=COLOUR&wpq_to=pa_COLOUR&wpq_ppp=100&wpq_offset=0&wpq_post_type=product&wpq_post_status=any

The plugin should list all of the IDs of the products that have been updated. If it only says "Done!" that means that the plugin did not find a matching term for the "to" variable.

@jonfitzgerald

This comment has been minimized.

Copy link

@jonfitzgerald jonfitzgerald commented May 1, 2019

Thanks so much for this!

I’m having some trouble though, keep receiving the “Done!” message without any products being updated. Both variables are set correctly.

Is there anything else I should check?

@Majed-RO

This comment has been minimized.

Copy link

@Majed-RO Majed-RO commented May 28, 2019

A small modification:

instead of ( line 91 ):
// Remove the product meta attribute:
unset( $meta[$from] );

replace it with:
// Remove the product meta attribute:
unset( $meta[$key] );

Because in some cases if you write the custom attribute in a capital letter, it will not unset it.

@wickywills

This comment has been minimized.

Copy link

@wickywills wickywills commented Jul 10, 2019

Doesn't seem to work correctly. For example, I have an attribute named "L/XL", but running this script creates a new attribute called "lxl" and doesn't use the one I created.

@thomastruett

This comment has been minimized.

Copy link

@thomastruett thomastruett commented Nov 18, 2019

Are you aware if it is possible to execute the script above and also maintain the variation relationships that were created using the custom attributes? For example, I am migrating from a custom attribute (size) to a taxonomy attribute (pa_size). Before the migration, one of my products has 5 variations based on the custom attribute size (e.g. 10, 12, 14, 16, 18). After I run the migration, it appears that all of the product variations have been orphaned (screenshot attached) and have to be manually re-created.
Screen Shot 2019-11-17 at 18 40 38

@chillpilllike

This comment has been minimized.

Copy link

@chillpilllike chillpilllike commented Aug 14, 2020

the code is not working with latest woocommerce

@chillpilllike

This comment has been minimized.

Copy link

@chillpilllike chillpilllike commented Aug 14, 2020

gives the error There was an error somewhere and the terms couldn't be set for post_id

@jlapitan

This comment has been minimized.

Copy link

@jlapitan jlapitan commented Aug 17, 2020

Error message says - ** Invalid taxonomy.**

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