2

I am using the Transients API to cache category loops for a custom taxonomy. All works fine, but if I add a new post or update an existing one, I woud like to compare the taxonomy values and then clear the transients based on the difference in IDs and then clear the others. Transients have the following format, _transient_mouldings_cat_loop_141 where 141 is the ID.

Does anyone have any suggestions on grabbing the tax values before the post is saved (existing terms) (which I thought would be category_save_pre(), but that only references post categories, and then on-save, use save_post() to grab the new values, find the difference and then delete the needed transients?

Thanks!

Update

I was able to delete category transients with save_post():

function mouldings_delete_transient_teaser($post_id) {
    switch (get_post_type()) {
        case 'moulding_profiles':
            // delete teaser transient
            delete_transient('mouldings_moulding_profiles_teaser_'.$post_id);

            // delete profile category transient
            $post_terms = get_the_terms($post_id, 'profile_categories');
            foreach ($post_terms as $post_term) {
                delete_transient('mouldings_cat_loop_'.$post_term->term_id);
            }
            break;
    }

}
add_action('save_post','mouldings_delete_transient_teaser');

but I still need to be able to plug into the initial load. I was thinking load_(page) might do the trick, an I could possibly create a function in there that grabs the posts before an item is saved, but then calling that function in save_post() would probably just give me the new categories (which I already have). Any suggestions are welcome

Thoughts

I'm wondering if this is more along the lines of storing the category IDs in a session variable - then on save_post() compare those with get_terms() (which will have the new ones) and then the unique IDs would be run through the delete_transient() function --- as I have still yet to come across anything...

Thoughts continued:

It sounds like sessions are not used in WordPress and while you can enable them via wp-config.php, I'm wondering if there is a simpler way that I'm missing.

Update #2

After more than a few back 'n forths with Tom, I believe this is the correct way to go:

function mouldings_delete_transients ($object_id, $terms, $tt_ids, $taxonomy, $append, $old_tt_ids) {

    if (get_post_type() == 'moulding_profiles' || get_post_type() == 'moulding_combination') {
        $changed_cats = array_diff($tt_ids, $old_tt_ids);
        foreach ($changed_cats as $changed_cat) {
            delete_transient('mouldings_cat_loop_'.$changed_cat);
        }
    }
}
add_action('set_object_terms', 'mouldings_delete_transients', 10, 6);

The only problem I'm having with this is $old_tt_ids are not being called when a post is saved. So, what I'm trying to do is compare the current categories, $tt_ids with the old categories, $old_tt_ids and detect the changes between the two. So, if a new category has been chosen, that would be part of the diff. And, if a category was removed (unchecked), that would also be chosen. It seems to grab the new ones, but not the old ones. Anyone have any ideas? Thanks!

7
  • I am not following what exactly are you cashing and what data is involved. Please try to make more clear what are you storing and what your cache invalidation conditions precisely are.
    – Rarst
    Oct 9, 2012 at 22:40
  • Hi @Rarst thanks for the reply. I am caching the WP_Query that generates each taxonomy (example). The problem isn't the caching itself, it's more clearing those transients that are attached to each category loop. Each category transient is appended with the cat id, so what I'm trying to do on post-save, is compare the categories it now has to the ones it did have and if there are any differences, delete those transients (whether categories were removed or added). I have 'em set to expire after an hour, but I'd like it to be more seamless. Thanks!
    – Zach
    Oct 10, 2012 at 14:54
  • It should be enough to delete the transient, any future attempt to grab it should force a recreation. You should post your transient deletion on save code as an answer and mark it as correct
    – Tom J Nowell
    Oct 10, 2012 at 15:05
  • Hi @TomJNowell to clarify, the transient appends on the category ID to the end of the transient name (as mentioned in the OQ), so even if there were a way to "wildcard" all int values at the end of the transient name, it defeats the purpose of using a "russian doll" effect of caching very specific parts of the site (so that when a transient is cleared, there's less for it to do to regenerate). I'm trying to get a list of the categories attached to a post "before" save, but "on-save", compare them and if there are differences, use those cat ids to delete the needed transients.
    – Zach
    Oct 10, 2012 at 15:38
  • then hook into the term setting..
    – Tom J Nowell
    Oct 10, 2012 at 15:51

1 Answer 1

5

Use the set_object_terms hook,

http://adambrown.info/p/wp_hooks/hook/set_object_terms?version=3.4&file=wp-includes/taxonomy.php

It should be fired when a post or page is modified.

Here is the code that fires it:

do_action('set_object_terms', $object_id, $terms, $tt_ids, $taxonomy, $append, $old_tt_ids);

You can thus check against the $object_id and taxonomy, and flush your transient cache and regenerate as needed.

Specifically, clear the term caches of the term IDs in $tt_ids and $old_tt_ids

20
  • Hi @TomJNowell thanks for that. I took a look and saw that the $old_tt_ids was added a few years ago. The wp_set_object_terms has a $delete_terms variable that looks to have exactly what I need (as it compares the old and new), but I'm a little unclear on how I can access that from within save_post. Would you be able to show me an example of that? It doesn't look like $delete_terms would have the new ones (hence the var name), so I'm assuming I would also keep my original delete_transient() func on the new ones. Thanks again.
    – Zach
    Oct 10, 2012 at 21:00
  • Don't access it from save_post, that's a different, separate, unrelated hook. It's also negligent of the fact that one may modify the terms fo a post without saving/editing/publishign said post.
    – Tom J Nowell
    Oct 10, 2012 at 22:27
  • Instead, assume that when the terms of an object are set in the taxonomy you are watching, that the terms will have changed, else that hook would never have been called. You already have everything required passed via the filter, stop overcomplicating things by requesting variables that contain data you already have ( old_tt_ids? not that you even need to check those!! If it's the taxonomy you're watching, and the object type you want, clear the transient, it's as simple as that, stop confusing things )
    – Tom J Nowell
    Oct 10, 2012 at 22:29
  • Also what would you do if you had access to the delete_terms variable? Do a get_Term call? But wait those terms have been deleted and are no longer in the DB! I can see you'll want to find an earlier hook then, but wait, if the terms never changed, the hook would never have been called...
    – Tom J Nowell
    Oct 10, 2012 at 22:31
  • 1
    That's a lot of posts to grab and display, just be careful your Russian dolls caching doesn't get too deep, I'd say using taxonomies as caches to speed things up would be a good idea, but I suspect you're already doing that
    – Tom J Nowell
    Oct 11, 2012 at 9:03

Your Answer

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

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