2

Assume that I have created following category.

  1. Mobile

If the post title has any of "mobile","Nokia","Samsung" these tags I need to set that post to Mobile category.

I can do it for new posts, I need to do it for old posts. I don't know how I do it for old posts.

2

Here is some rough code for you, you may improve the query if you like...

By the way selecting post_title and post_status is not neccessary, but useful if you want to ensure that you are returning the right results via conditional logic within your foreach loop.

global $wpdb;

$results = $wpdb->get_results(
    "
    SELECT ID, post_title, post_status
    FROM {$wpdb->prefix}posts
    WHERE post_status = 'publish'
    AND (post_title LIKE 'mobile'
    OR post_title LIKE 'Nokia'
    OR post_title LIKE 'Samsung')
    "
);

foreach($results as $result) {
    wp_set_object_terms($result->ID, array('Mobile'), 'my_taxonomy');
}

Recommended reading:

Update

Based on your comment:

The problem is I need to do this for nearly 100 categories. I can write 100 queries for it. The problem is, will I have to face a performance problem?

You don't have to write 100 queries for this, instead you can abstract the process into something more manageable.

If you know the categories and the titles that you want to associate with the categories then you can create an array like this following by logic to iterate over your categories which forms the SQL statement, executes the query and then updates the post objects based on the results:

set_time_limit(0); //hopefully by pass your server config

global $wpdb;

$categories = array(

    //category          post titles to search for
    //  ↓                 ↓        ↓         ↓
    'mobile' => array('Nokia', 'Samsung', 'Mobile'),
    'tablets' => array('iPad', 'iPad mini', 'Surface Pro 4')

    //etc...

);

$sql =<<<DOC
    SELECT ID, post_title, post_status
    FROM {$wpdb->prefix}posts
    WHERE post_status = 'publish'
    AND (%s)
DOC;

foreach($categories as $category => $titles) {

    $like = array();

    foreach($titles as $title) {
        $like[] = "post_title LIKE '{$title}'";
    }

    $results = $wpdb->get_results( sprintf($sql, implode(' OR ', $like)) );

    foreach($results as $result) {
        wp_set_object_terms($result->ID, array($category), 'my_taxonomy');
    }

}

If you have to run many queries, a few hundred or thousands even, then you should consider batch processing/cron job execution.

If you want case-insensitive queries then you can do:

$like[] = "LOWER(post_title) LIKE LOWER('{$title}')";
4
  • Thanks, I followed links given by you. As I understand it, if I use wp set object terms I don't even to set categories when publish a new post. As I understand above code, it can handle old posts and new posts. Am I correct? – Damith Feb 22 '16 at 4:37
  • Correct, you can use that function anytime you wish to programmatically add terms to a post object. If your post_type is a custom type, then you use wp_set_object_terms() as I showed in my example, where as wp_set_post_terms() only works for a post_type of post. So you have two options depending on your situation. I would just use: wp_set_object_terms(). Make sure you read the documents on how to supply the correct term by name or by ID. – Adam Feb 22 '16 at 4:39
  • Thanks, I have implemented it. It worked as I want. The problem is I need to do this for nearly 100 categories. I can write 100 queries for it. The problem is, will I have to face a performance problem? – Damith Feb 22 '16 at 6:33
  • See edit above... I give you a basic suggestion to get going, you can modify it/improve it to suit your needs. – Adam Feb 22 '16 at 8:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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