SSL error when upgrading a WordPress Multisite Network

When updating to WordPress 4.0, I recently saw a scary-looking error when running the database upgrade on a network with some SSL sites. It triggered when trying to update tables for a site with an SSL certificate.

Warning! Problem updating https://blog.network.com/. Your server may not be able to connect to sites running on it. Error message: SSL certificate problem, verify that the CA cert is OK. Details: error:14090086:SSL routines: SSL3_GET_SERVER_CERTIFICATE: certificate verify failed

To be totally honest, I’m not exactly sure why this happens, but I was able to find a way to fix it by telling WordPress to ignore SSL checks when running the database upgrade. Create a file in wpcontent/mu-plugins/ and name it something like network-upgrade-ignore-ssl.php. Put the following in the file:

<?php
add_filter('https_ssl_verify', '__return_false');
add_filter('https_local_ssl_verify', '__return_false');
?>

That’s it! You should now be able to get through your upgrade smoothly.

Remove a specific TinyMCE item from the WordPress editor

When filtering a row of TinyMCE buttons, here’s a way to remove a specific button by name. This is useful for cases where you’re editing the default editor instead of declaring your own editor. In this example, we’ll remove the underline button from the second row:

function my_mce_buttons_2( $buttons ) {
	$index = array_search( 'underline', $buttons );
	if ( $index !== false ) { unset( $buttons[$index] ); }

	return $buttons;
}
add_filter( 'mce_buttons_2', 'my_mce_buttons_2' );

Drop that code in your functions.php file to remove a specific item from your WordPress editor buttons. For more information about the individual TinyMCE toolbars available see this codex page. To list all buttons by name for a given toolbar, temporarily add print_r( $buttons ); to your filter callback function.

Determine if a WordPress post or page has children

Here’s a simple function to determine if a post, page, or custom post has children in WordPress. It works by getting the children of the current post and returning a count. It will return 0 (false) if there are no children and some positive integer (true) if there are children.

function has_children() {
	global $post;
	return count( get_posts( array('post_parent' => $post->ID, 'post_type' => $post->post_type) ) );
}

Use it in your page or post templates:

if ( has_children() ) {
	// do something if this item has children
}

Clean up a bloated wp_term_relationships table

Sometimes the wp_term_relationships table becomes bloated with many orphaned relationships. This happens particularly often if you’re using your site not as a blog but as some other type of content site where posts are deleted periodically. I recently worked on a site that had 18,000 term relationships for posts that no longer exist, and it was slowing the site down. In my case it was the way a real estate plugin from Placester IDX manages real estate listings, but you may find similar problems caused by other custom functionality.

Fortunately, MySQL can help you find these orphaned relationships with a pretty simple query:

SELECT * FROM wp_term_relationships
    LEFT JOIN wp_posts ON wp_term_relationships.object_id = wp_posts.ID
    WHERE wp_posts.ID is NULL;

It can even automatically delete the orphaned entries for you! Make sure you back up your database before running the following query:

DELETE wp_term_relationships FROM wp_term_relationships
    LEFT JOIN wp_posts ON wp_term_relationships.object_id = wp_posts.ID
    WHERE wp_posts.ID is NULL;

The number of rows deleted should match the number of rows returned in the SELECT query above.

Once you’ve deleted the unnecessary items, make sure to optimize the database table.

OPTIMIZE wp_term_relationships;

Prevent WordPress from guessing if users hit a 404 error

Update: I’ve put together a plugin for this. It’s only a few lines of code, but if you don’t want to add it to your site manually, you can now use the Stop 404 Guessing plugin.

WordPress has a feature called Canonical Redirects which attempts to make sure that users always end up on the one true URL for a given request. That’s great for SEO. Built in to this feature, however, is something that mystifies a lot of developers: when a user reaches a 404, WordPress will use some fuzzy matching try to guess what they meant and redirect them.

To me, this is pretty much the polar opposite of a canonical redirect. I’d much rather have 404s result in a helpful 404 page which I can track in analytics. It can also be very confusing when you’re trying to add your own rewrite rules to WordPress.

Fortunately, you can filter the Canonical Redirect to prevent this strange 404 behavior. Add this to functions.php in your theme:

function stop_404_guessing( $url ) {
	return ( is_404() ) ? false : $url;
}
add_filter( 'redirect_canonical', 'stop_404_guessing' );

Now WordPress will continue redirecting to the canonical URL, unless you hit a 404 in which case it will display your 404 page as expected.