WordPress function leads to endless fun

Came across a fun one today. A person in the WordPress.org Support Forums wanted a function that would set a post status to Private if the post was assigned to a certain category. My approach was to prevent future posts from not missing out on the opportunity to set the status and does not really address posts that are already in the database.

To start things off, I wandered over to the WordPress Codex for the wp_update_post function and adapted the example listed.

function post_saved_set_to_private ( $post_id ) {
if ( in_category( 'switcheroo' )) {
	// Update post with the following
	  $my_post = array( 'ID' => $post_id, 'post_status' => 'private' );

	// Update the post into the database
	  wp_update_post( $my_post );

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

Talk about easy! I tossed this function into my theme’s functions.php file so I could try things out on my localhost installation. I was going to be the original poster’s savior.

I tried creating a regular post in a random category. Success! Now the real test — add a new post in the switcheroo category. Hit Publish. Why is it taking so long? What’s the deal? I’m dead in the water. Nothing is happening. This can’t be good. I opened up a new tab to my Dashboard and jumped into All Posts. 900+ new posts set to Private! Hey, that’s not right! So while I set to work on deleting those posts (200 at a time), I began to think about what had happened and I figured it must have something to do with post revisions.

Indeed. Now here’s the good part. If I had only scrolled down the wp_update_post Codex page just a little more, I would have avoided the problem I had created.

===Caution – Infinite loop===
When executed by an action hooked into save_post (e.g. a custom metabox), wp_update_post() has the potential to create an infinite loop. This happens because (1) wp_update_post() results in save_post being fired and (2) save_post is called twice when revisions are enabled (first when creating the revision, then when updating the original post—resulting in the creation of endless revisions).

If you must update a post from code called by save_post, make sure to verify the post_type is not set to 'revision' and that the $post object does indeed need to be updated.

function my_function( $post_id ) {
	if ( ! wp_is_post_revision( $post_id ) ) {
	
		// unhook this function so it doesn't loop infinitely
		remove_action('save_post', 'my_function');
	
		// update the post, which calls save_post again
		wp_update_post( $my_args );

		// re-hook this function
		add_action('save_post', 'my_function');
	}
}
add_action('save_post', 'my_function');

In the example above, you see a check to make sure that the post is not a revision. If that passes, the function then removes the action, does the update and then adds action back again. This is how you avoid an infinite loop and finding out you have 900+ posts that you didn’t want at all.

Armed with new information, I updated my original function to include the crucial part about avoiding an infinite loop and came up with the following function.

function post_saved_set_to_private ( $post_id ) {
	if ( ! wp_is_post_revision( $post_id ) ) {

		// unhook this function so it doesn't loop infinitely
		remove_action('save_post', 'post_saved_set_to_private');

		if ( in_category( 'switcheroo' )) {
			// Update post
		    $my_post = array( 'ID' => $post_id, 'post_status' => 'private' );

			// Update the post into the database
			wp_update_post( $my_post );
		}

		// re-hook this function
		add_action('save_post', 'post_saved_set_to_private');
	}
}
add_action('save_post', 'post_saved_set_to_private');

I believe I got the function working and learned a little something along the way.

From “Strayhorn” to “Powell”

I had a brief conversation with Matthew on the Slack #forums channel that spurred some memories about what I think was my earliest use of WordPress.

A #forums Slack conversation I had with Matthew.

Back in February of 2005, Matt Mullenweg introduced “Strayhorn” and released WordPress 1.5 to the world.

Announcing WordPress 1.5

(This is my favorite part of what I do.) To the 12,126 of you who have already downloaded WordPress 1.5, congrats for being on the ball. We had a “soft launch” on Monday the 14th while we worked out some infrastructure issues and we’re now very ready to announce WordPress 1.5 to the world. This release is named “Strayhorn” in honor of Billy Strayhorn the pianist and sublime composer who worked closely with Duke Ellington and wrote tunes like “Take the A Train” and “Lush Life.” We thought he was perfect to represent the power and elegance of this release, which has been under intense development and testing the past few months.

I’m not sure I can definitively say that “Strayhorn” was my first use of WordPress, but it’s certainly a moment in WordPress’ history that I can definitely remember. Pages were introduced, the plugin repository became a thing and theme templates continued to evolve as did spam mitigation. I was so impressed with Kubrick (the default template for WordPress) and then Michael Heilemann rolled out K2. Wow! I really thought that theme was cool. Heilemann introduced some other concepts that were later adopted like widgets and a settings page for themes.

All the stuff we see and do with WordPress today started with some very humble beginnings and has grown tremendously in the last ten years. The “Strayhorn” release seems like it was a huge turning point and I feel pretty fortunate that I was able to witness a chunk of it in those early days.

I’m back!

After a long absence of not having a blog, I’ve returned. There was a time where I was running a self-hosted blog on schulte.mn, but I found that I just didn’t write enough to continue to pay for hosting. I thoroughly enjoyed playing with WordPress nightlies and having the ability to install whatever plugin or theme I wanted. If I want to break things again, I’ll just do it on localhost and be done with it. It’s probably for the better anyway. No more worrying about having my blog not working or displaying correctly. No more will I pay for hosting and not actually use it. I won’t worry about posting. I’ll just post when I want.

My entire, small history of the old blog is long gone. I won’t miss it much. Sure there are few posts that I wouldn’t mind seeing again but I’ll just start with the clean slate and move forward.

Here we go!