Two WordPress functions I can’t do without

These two remove the awful tedium of writing filter functions that just return things or append things to arrays. Inspired by ‘__return_true’ and ‘__return_false’ from WP core.

function __provide( $var ) {
	return function() use ( $var ) {
		return $var;
	};
}

function __append( $var ) {
	return function( $arr ) use ( $var ) {
		$arr[] = $var;
		return $arr;
	};
}

Usage example

Before:

add_filter( 'excerpt_more', 'my_remove_excerpt_more' );
function my_remove_excerpt_more( $excerpt_more_string ) {
	return '';
}

After:

add_filter( 'excerpt_more', __provide( '' ) ); 

A better way to handle POSTs in WordPress using closures

Ever find yourself doing this? Repeating the entire logic of a basic POST, only to change some minute detail of the function. The only difference between the two functions below is the meta_key.

add_action( 'save_post', 'update_my_meta_value' );

function update_my_meta_value( $post_id ) {
    if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
        return;
    }

    if ( !wp_verify_nonce( $_POST['my_nonce'], 'nonce' ) ) {
        return;
    }

    if ( wp_is_post_revision( $post_id ) ) {
        $post_id = wp_is_post_revision($post_id);
    }

    $meta_value = intval( $_POST['my_meta_value'] ); // sanitize

    // ok, update the single meta value I just posted
    update_post_meta( $post_id, 'my_meta_key', $meta_value );
}

add_action( 'save_post', 'update_another_meta_value' ); 

function update_another_meta_value( $post_id ) {
    if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
        return;
    }

    if ( !wp_verify_nonce( $_POST['my_nonce'], 'nonce' ) ) {
        return;
    }

    if ( wp_is_post_revision( $post_id ) ) {
        $post_id = wp_is_post_revision($post_id);
    }

    $meta_value = intval( $_POST['another_meta_value'] ); // sanitize

    // ok, update the single meta value I just posted
    update_post_meta( $post_id, 'another_meta_value', $meta_value );
}

This is hideous. Globals, repetition, etcetera. We can dramatically clean it up with a simple closure.

function db_post_handler( $callback ) {
    return function( $post_id ) use ( $callback ) {
        if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
            return;
        }

        if ( !wp_verify_nonce( $_POST['my_nonce'], 'nonce' ) ) {
            return;
        }

        if ( wp_is_post_revision( $post_id ) ) {
            $post_id = wp_is_post_revision($post_id);
        }

        call_user_func( $callback, $post_id );
    };
}

This way we can bang out functions that have *some* logic in common, and we can hand the result straight to add_action:

function update_my_meta_value( $post_id ) {
    // all the nonce-checking etc is something else's responsibility
    // so i can focus on what i wanted to do
    $meta_value = intval( $_POST['another_meta_value'] ); 
    update_post_meta( $post_id, 'another_meta_value', $meta_value );
}

add_action( 'save_post', db_post_handler( 'update_my_meta_value' ) );

Benefits:

  • Remove duplication
  • Clearer intention in the functions that do the actual updating
  • More secure (in that you can’t forget to do nonce-checking etc)
  • Testable functions that don’t depend on globals

Retrieving a password you accidentally deleted from your OS X Stickies

If you are careless, you regularly delete stickies containing important information. Thankfully, your Tax ID code is a 12-digit number.

# OSX may have left an old copy of the stickies lying around. this is where we will look.
# get the stickies and back them up
$ cd /Users/[you]/Library/Preferences/
$ mkdir ~/stickybackup
$ cp *.stickies.plist* ~/stickybackup
$ cd ~/stickybackup
# we want to grep the .plist files, but they're technically binary blobs
# so we must convert them. repeat for each file - i can't write bash loops
$ plutil -convert xml1 -o - [your sticky filename] > plain_text.txt
$ grep '[0-9]\{12\}' plain_text.txt 

cf: http://apple.stackexchange.com/questions/101719/trouble-opening-plist-files-in-text-editor and https://discussions.apple.com/thread/1231501

Drive-by recursion in PHP

PHP does not make it easy to program with recursion offhand, but it’s possible. This is from a WordPress function which needed to get IDs from terms and all their parents:

// get the term ids from this term and all its parents
$all_ids = call_user_func($func = function( $term, $ids ) use ( &$func ) {
    if( !$term ) { return $ids; }

    $ids[] = $term->term_id;
    $next_term = get_term_by( 'id', $term->parent, $term->taxonomy );

    return call_user_func( $func, $next_term, $ids );
}, $term, array() );