I'm writing a plugin for importing products and categories from another CMS into Wordpress (with Woocommerce). To keep the structure of categories and to put products into the right categories I would like to use custom IDs (not the ones generated by Wordpress) of categories from the source CMS instead of category names as a reference.

The default category arguments look like this:

$default = array(
    'name'             => '',
    'slug'             => '',
    'parent'           => 0,
    'description'      => ''

I need to add a reference field that would store the ID from the source CMS, like so:

$args = array(
    'name'             => 'Name of the category',
    'slug'             => 'name-of-the-category',
    'parent'           => 0,
    'description'      => 'My category',
    'ref_id'           => '53113'

I've read a few articles about adding custom fields to the category and it looks like the best way for this would be to use term meta, something like this:

// After I've created the category and saved its' ID in $cat_id
// I add a termmeta for this category
add_term_meta($cat_id, 'ref_id', '53113', true);

But now the question is how do I search for a category with this ref_id? Do I have to loop through all term meta with key ref_id and search for '53113'?

Isn't there a faster way to get the ID (assigned by Wordpress) of the category with ref_id of 53113? Something like:

// Fictional function that would be perfect,
// returns category ID assigned by Wordpress
$cat_id = get_cat_by_meta('ref_id', '53113');

I need to use ref_id because category names are not unique (there could be categories with same names under different parent categories) and I think it would be the fastest way to copy the structure from the source CMS. Another reason why I need it this way is because the source CMS is not aware of Wordpress structure or available categories and their ID's. Instead of figuring out the right category and the right parent every time I could just say put the product/category into category with ref_id equal to '53113'.

I hope I explained the issue and the goal clearly, if not, please leave a comment so I could improve the question.

Update: possible solution with an SQL Example

Perhaps I could just use a query like this:

global $wpdb;
$results = $wpdb->get_results("SELECT term_id FROM wp_termmeta WHERE meta_key = 'ref_id' AND meta_value = '53113' LIMIT 1");

I guess it should work and to me it looks like a simple enough solution (of course I'd need to also do $wpdb->prepare with variables inside of the query). But I'm not sure if that's the best practice in Wordpress.

So should I just use this custom query or is there be a better way?

1 Answer 1


You can use get_terms():

$args = array(
    'taxonomy' => 'name-of-the-category',
    'meta_query' => array(
            'key'       => 'ref',
            'value'     => '53113',
$terms = get_terms( $args );

You would get an array of terms, where the ref value would be 53113.

  • Can I omit the 'taxonomy'? If not then I'd need an extra field in my input (right now the source provides only the ID of the parent category, which I use as a meta reference). Also do I need to sanitize the values before using them in get_terms? Oct 21, 2016 at 9:18
  • Hmm, actually shouldn't the taxonomy be equal to 'product_cat'? Oct 21, 2016 at 9:26
  • Yes, I think you should know the taxonomy, since you are creating the terms, right :) "do I need to sanitize the values" it can't harm to use a (int) Oct 21, 2016 at 9:35
  • Yes, when I create them, but I also sometimes need to provide the parent ID for the category that I'm creating and the ID in my source data is not equal to the ID assigned by Wordpress, that is why I'm storing this meta value in the first place. So in some queries I'm only interested in the parent ID and not its name. (int) could work, but my IDs actually can contain letters... In any case, I think your answer is a proper solution for such a task and if someone needs something more specific, they can run a query similar to the one that I provided in the update. So I'll accept your answer. Oct 21, 2016 at 9:56
  • 1
    It's just tricky to explain the issue without providing the full code and I think it would be too much of it for the format of this website. And my solution is working fine anyway (once again, the algorithm that I use is not generic enough to post it here, I think). Anyway, thanks for the help! Oct 21, 2016 at 9:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.