0

I'm setting a meta field for the category and getting the meta value of each field like this:

$cat_meta = get_option( "meta_field_$cat1" );
if (isset($cat_meta['color'])){
    $cat1_color = $cat_meta['color'];
}

Can I get the non empty meta field value of all categories using a loop?

2 Answers 2

0

If you'd use the get_categories() function to get all the categories, you can then loop through them. Partial pseudo code, but this will do the trick:

$categories = get_categories( array() );
$colors = array();

foreach ( $categories as $category ) {
$cat_meta = get_option( 'meta_field_' . $category->slug );
if (isset($cat_meta['color'])){
    $colors[ $category->term_id ] = $cat_meta['color'];
}
}

PS. I don't know if the field in the options table is using the slug or the category id. The colors array will be filled with id's of the category as key and value of the meta field as value.

PPS. get_categories() function call might need some extra parameters in the array, adjust to your liking using the available parameters.

PPPS. While my answer technically answers this question, this answer by s_ha_dum is actually a better approach (might require some more refactoring though).

1

Using get_categories as in @CoenJacobs answer is one way to go. A Loop like that may not be very efficient, though.

get_option does not allow you to search by wildcard, which due to the way you have constructed your keys -- is what you would need to avoid the loop, but a simple query like this would do it:

$cat_meta = $wpdb->get_results("SELECT option_name,option_value FROM {$wpdb->options} WHERE option_value != '' AND option_name LIKE 'meta_field_%'");

Your loop would then look like (if I am not reading things wrong):

foreach ( $cat_meta as $meta ) {
  if ('color' == $meta['option_value']){
    $colors[ $meta['option_name'] ] = $meta['option_value'];
  }
}

When I see the need for something like that, I always wonder if the real problem isn't how the data is stored. You may want to consider storing your category meta as a serialized array under a single key. Whether that is a good idea or not depends on a couple of things:

  1. How much data do you need to store in the key?
  2. Do you need to query by individual values stored in the key?

While you can store a lot of data in a single key when you retrieve it you always have to retrieve all of it and process all of it. That may not be any more efficient than the query above.

Trying to search for, say a particular color name inside a serialized array/object using SQL is extremely inefficient and error prone.

The actual mechanics of storing and retrieving the array/object are simple. WordPress pretty much does the work for you.

add_option('test_option_name',array('a','b','c'));

var_dump(get_option('test_option_name'));
3
  • You're right. The reason why I picked the loop version is because that preserves the relation between the option value and the category (via id). If you want to do that with your solution, you'll need to query the option_key as well and loop through it to restore that relation. I think a loop is inevitable if you want to do something useful with this data. I fully agree with the fact that this might not be the optimal data storage though, the serialised array might be the best solution. Jun 29, 2013 at 21:22
  • Thanks so much for your answer and suggestion, wish I could upvote. Could you please give an example of storing category meta as a serialized array like you mentioned? I just need to add an extra field color on the category page.
    – ajay
    Jun 29, 2013 at 21:23
  • 1
    @CoenJacobs : You only need to add option_name to the query (I've altered the answer) to keep that relationship, but any Loop that might have to happen only has to happen over values that have information, which is the point, and not over every category in the database which is very wasteful if you have 400 categories and only 10 of them with meta_field_* values.
    – s_ha_dum
    Jun 29, 2013 at 21:36

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.