• Resolved Andreas 2013

    (@andreas-2013)


    Hi everybody,

    I have a database with a custom post type “person” with thousands of pages. Each person’s age is calculated using a custom field (e.g. 1964-02-15) and is then stored as a taxonomy term, when the post is saved (I need the age as taxonomy).

    That works correct with this code in my functions.php:

    function calculate_age($post_id) { 
    //...code to calculate the age of the person...
    wp_set_object_terms( $post_id, $interval, 'age');
    }
    add_action('save_post','calculate_age',100, 2);
    }

    In order to keep the age up to date now, I would like to have the posts automatically saved overnight, so that the taxonomy term is always correct. I know there is a WordPress cron function, to do things automatically. But how can I save all posts of my custom post type to execute the above function? I’ve tried various code snippets I found on the web (wp_schedule_event, register_activation_hook, wp_update_post etc.) but it seems, I’m just messing up the correct way to do it.

    I would be very happy, if someone could tell me how to do it step by step 🙂

    Thank you very much in advance!
    Andreas

Viewing 9 replies - 1 through 9 (of 9 total)
  • Topher

    (@topher1kenobe)

    I don’t think you want to do it on post save, you’re going to run out of resources fast that way.

    I would write a script that does these things:

    1. custom db query to get all dates, with post_ids as the keys.
    2. verify you got good data
    3. remove all terms from the age taxonomy
    4. loop over the dates, do your calculation, and use wp_create_term() to create the proper terms with values and post_id relationships.

    This is going to run WAY faster than actually saving all your posts.

    As for cron, I don’t personally like WP-Cron, it’s not super reliable. In your script do a test for a GET var, something like this:

    if ( ! empty( $_GET['get_ages'] && $_GET['get_ages'] == true ) {
      // DO STUFF
    }

    Then use any other cron to do an http request to your homepage with ?get_ages=true at the end. Run it once at midnight or something. You can use the command line cron on your server if you want, or from your own machine (unreliable), or there are web services which will let you pay $1/mo or something to run a command on cron.

    • This reply was modified 2 years, 2 months ago by Topher.
    Moderator bcworkz

    (@bcworkz)

    What is the actual need for the age taxonomy term? It seems to me like there should be a better way. Having redundant data isn’t good. Since age and birth date are inter-related, I see this as redundant. And having data that needs to be constantly updated over time should be avoided as well.

    Let’s say for example, the term would be used to get all persons aged 39 years. It’d be simple to get all persons assigned the “39” term. Fair enough, but you could also query for all persons whose birth date custom field falls in a certain range, avoiding any need for redundant data or having to update assigned terms.

    Topher

    (@topher1kenobe)

    The taxonomy query is going to be WAY faster than a custom field query with math in it. Plus as a term you can do all sorts of other interesting things like make data maps of age groups, without every hitting the posts table.

    Thread Starter Andreas 2013

    (@andreas-2013)

    Thank you both so much for the good advices!

    Yes, Topher, you’re right. The reason I want to use taxonomies is for better performance. I first tried to do the queries with custom fields, but it took too long. That’s how I came up with the idea of ​​the taxonomies. In addition to the age calculation, I also have various other values ​​that I output with taxonomies, such as places of birth, zodiac signs, etc. The output is very convenient and very fast. Actually I wanted to use only my custom table with the custom fields. But the benefits of taxonomies are worth it, I think.

    Topher, I’m a wordpress beginner and not that good at creating complex queries. Could yo explain it a little bit, how would you do the queries exactly?

    Thanks in advance!

    Topher

    (@topher1kenobe)

    First use a tool like phpMyAdmin to look at the postmeta table and find your custom fields. Is the date stored in plain text like 2022-10-01 or is serialized somehow? Plain text is preferred, but we could work with serialized.

    Read about $wpdb: https://developer.wordpress.org/reference/classes/wpdb/

    That makes it easy to send a custom query. Something like this:

    $birth_dates = $wpdb->get_results(
        "SELECT post_id, meta_value FROM {$wpdb->postmeta} WHERE <code>meta_key</code> = 'YOURKEYNAME'"
    );

    where YOURKEYNAME is whatever you called your birthdate field.

    I don’t know for sure what the format will be coming back from that, but to be sure then you can do something like this:

    $birth_dates_array = [];
    foreach ( $birth_dates as $birth_date ) {
        $birth_dates_array[ $birth_date->post_id ] = $birth_date->meta_value;
        // it might be this instead:
        // $birth_dates_array[ $birth_date['post_id'] ] = $birth_date['meta_value'];
    }

    then you’ll have an array that looks like this:

    [
    1,'2022-10-01',
    2,'1971-07-17'
    ]

    then it’s a plain array. Use foreach to loop over it and use wp_set_post_terms (I misspoke about wp_create_term above) to connect posts to terms.

    • This reply was modified 2 years, 2 months ago by Topher.
    Thread Starter Andreas 2013

    (@andreas-2013)

    Fortunately I’m using a custom table, not the wp_postmeta-table, maybe it makes it easier? The date is plain text. Nevertheless it’s difficult to understand for me. Could you explain how to use wp_set_post_terms in this script? And in which file do I save the code to start it later via cron job?

    I’m going to bed now, it’s late in Germany 😉
    Thank you very much for your help! See you tomorrow!

    • This reply was modified 2 years, 2 months ago by Andreas 2013.
    Topher

    (@topher1kenobe)

    The custom table shouldn’t matter, you can just adjust the query accordingly. If you look stuff up in phpMyAdmin it’ll show you the query it used.

    The array I showed has post_ids as keys and dates as values. So you’d do something like

    foreach ( $birth_dates_array as $post_id => #term ) {
      wp_set_post_terms( $post_id, $term, 'WhateverYourTaxonomyIs' );
    }
    Thread Starter Andreas 2013

    (@andreas-2013)

    Hi Topher,
    $wpdb was a good tip, I’ve solved the problem 🙂
    Thank you again!

    Topher

    (@topher1kenobe)

    Rock on!

Viewing 9 replies - 1 through 9 (of 9 total)
  • The topic ‘Save all posts automatically and execute function’ is closed to new replies.