Viper’s Video Quicktags WordPress Plugin Discontinued

I’m officially discontinuing my Viper’s Video Quicktags WordPress plugin. It was one of the first plugins I ever wrote over 10 years ago. Back then embedding videos into WordPress posts was a chore and so I wrote the plugin to make the life of authors much easier.

Since then a lot has changed, namely the inclusion of native support in WordPress for even easier embeds, a feature that I actually contributed myself to WordPress.

Unfortunately users of my Video Quicktags plugin have been forced to keep the plugin activated so that embeds in old posts continue to work. Without the plugin, the shortcodes that the plugin created would cease working. So recently I wrote and released a tiny replacement plugin that creates those same shortcodes but has the native WordPress embed functionality handle the actual embedding of content.

If you are a Viper’s Video Quicktags plugin user, then I strongly recommend that you install my new plugin and then delete Viper’s Video Quicktags.

Besides switching away from a plugin I no longer support, advantages of the replacement plugin are modern, HTML5 embeds instead of Adobe Flash as well as automatic width to fit most themes, rather than fixed width independent of what theme you’re using.

It should be noted that the new plugin does not include the YouTube, Vimeo, etc. buttons in the editor but those are redundant due to how easy it is to embed videos directly from WordPress now — just paste the video’s URL on its own line.

Feel free to leave any questions or comments below.

My WordPress-Branded MacBook Pro

After four years at Automattic, you are given an awesome MacBook that has been customized by ColorWare to have a glowing WordPress logo instead of an Apple logo as well as being painted any color you wish.

My four year anniversary of being officially hired was last March (I was also on contract for 9 months) but as one of the handful of Windows users in the company, I originally opted to pass on the custom MacBook and stick with normal Windows laptops. I’ve used Windows for 20 years now and my primary machine is a very powerful desktop computer that I’ve built for gaming.

However I recently tried to use a Mac for something and realized that I had absolutely no clue how to use it. I didn’t even know about Finder! Yeah, pretty bad.

Additionally I saw some very cool looking customized MacBooks at my company’s annual full company meetup that made me want one too.

So I decided to get one after all and I’m super happy I did! It’s absolutely beautiful and I can install Windows on it so that I can use both operating systems.


  • 13″ MacBook Pro with Retina screen
  • 3.0GHz Dual-core Intel Core i7, Turbo Boost up to 3.5GHz
  • 16GB 1600MHz DDR3L SDRAM
  • 1TB PCIe-based Flash Storage

Here’s how they do the custom logo:

WordPress Appearance On “Orphan Black”

In the latest episode of the great TV show Orphan Black, a character is searching for something on the Internet and is for some reason viewing search results in the form of HTML (ooo, what a hacker!). If you look at the stylesheet URLs, you’ll notice “wp-content”, a sign that it’s a WordPress-powered site!

WordPress On "Orphan Black"

Before you bother to check, the domain is registered in real life but there’s no site there, WordPress or otherwise.

For other sightings of WordPress on television, check out these posts.

Ideal WordPress Plugin Development Using PhpStorm 8

The upcoming PhpStorm 8 features built-in WordPress support, as explained in this support document. However what’s the best way to set up your WordPress install in order to write plugins? Here’s my personal answer — feel free to suggest alternatives in the comments section.

When working on a WordPress plugin, you don’t want functions, classes, variables, etc. from other plugins to leak into your current plugin through auto-complete or other types of automation. For this reason, I suggest avoiding opening a whole WordPress checkout with all of your plugins inside of it using PhpStorm. At the same time, you don’t want to have a separate copy of WordPress for each plugin that you work on. This is redundant and makes keeping WordPress up to date harder.

So instead do a single checkout of WordPress to its own folder and then define WP_PLUGIN_DIR and WP_PLUGIN_URL, as described on the Codex, so that your plugins folder will live outside of your WordPress folder. This way you can open and index the WordPress folder without getting all of your plugins along with it.

Now create a new project for each individual plugin. When doing so, you’ll want to add the WordPress folder as an include path in PhpStorm, as described in their documentation.

All of this will result in only your individual plugin’s folder showing up in PhpStorm but with WordPress showing up under the “External Libraries” list. This one WordPress install can be used in your browser to test all of your plugins but the plugin codes won’t overlap.

Date Queries In WordPress 3.7+

Earlier today, a patch for WordPress that I’ve been working on got committed to WordPress trunk. “Trunk” is the in-development version of WordPress and will eventually become the next version of WordPress, in this case 3.7.

My patch introduces the ability to do complex date-based queries for fetching both posts and comments from the WordPress database. In the past, you could select posts that had a specific value for year, month, etc. but there was no way to do things like selecting all posts before (or after) a certain date or selecting all posts between two different dates. With my patch, this and more is now easily possible.

Here’s some examples:

// Get the 10 most recent posts made
// between 9AM and 5PM on weekdays
$some_posts = new WP_Query( array(
	'date_query' => array(
			'hour' => 9,
			'compare' => '>=',
			'hour' => 17,
			'compare' => '<=',
			'dayofweek' => array( 2, 6 ),
			'compare' => 'BETWEEN',
	'posts_per_page' => 10,
) );

// Get all posts from this summer
// June 1st to August 31st, inclusive
// Note that strtotime()-compatible strings can be used
$some_posts = new WP_Query( array(
	'date_query' => array(
			// String via strtotime()
			'after'     => 'June 1st, 2013',
			// Or if you want, an array
			'before'    => array(
				'year'  => 2013,
				'month' => 8,
				'day'   => 31,
			'inclusive' => true,
	'posts_per_page' => -1,
) );

// Any posts made over a year ago
// but modified in the past month
$some_posts = new WP_Query( array(
	'date_query' => array(
			'column' => 'post_date_gmt',
			'before' => '1 year ago',
			'column' => 'post_modified_gmt',
			'after'  => '1 month ago',
	'posts_per_page' => -1,
) );

It works for comments too:

// All comments from post ID 123
// that are within the past week
$some_comments = get_comments( array(
	'post_ID' => 123,
	'date_query' => array(
			'after' => '1 week ago',
) );

As you can see, the possibilities and combinations of cool things you can do are endless.

Here’s all of the possible arguments:

'date_query' => array(
	'column' => 'optional, column to query against, default is post_date',
	'compare' => 'optional, see WP_Date_Query::get_compare()',
	'relation' => 'optional, OR or AND, how the sub-arrays should be compared, default is AND',
		'column' => 'see above',
		'compare' => 'see above',
		'after' => 'string or array, see WP_Date_Query::build_mysql_datetime()',
		'before' => 'string or array, see WP_Date_Query::build_mysql_datetime()',
		'inclusive' => 'boolean, for after/before, whether exact value should be matched or not',
		'year' => '4 digit int',
		'month' => 'int, 1-12',
		'week' => 'int, 0-53',
		'day' => 'int, 1-31',
		'hour' => 'int, 0-23',
		'minute' => 'int, 0-60',
		'second' => 'int, 0-60',

Additionally, all of the old-school date and time arguments for WP_Query are now handled by my code as well. They will continue to work as before and you only need to use the date_query parameter if you want more advanced control of your results.

Questions? Anything you want me to clarify? Leave a comment below. 🙂

Important Security Update For SyntaxHighlighter Evolved

If you use my SyntaxHighlighter Evolved WordPress plugin, please update ASAP. There’s a security issue with the Flash file that is used by version 2 of the highlighting library. This file is meant to be used for allowing one-click copying of the code to your clipboard (since normal copy/paste doesn’t work with it) but the file reportedly suffers from a cross-site scripting security issue.

Even if you use the better version 3 of the library (the default for my plugin), the file from version 2 of the library will still be included in the plugin’s files.

As a temporary fix, I have emptied out the file. This unfortunately means your visitors will not easily be able to copy any code you paste. I recommend switching to the superior version 3 via my plugin’s settings page. Code highlighted using the newer version can be selected and copied normally.

Feel free to leave any questions you have about this security issue on this post but please leave other general SyntaxHighlighter comments on the plugin’s homepage. Thanks.

WordPress: Debug Functions Attached To A Filter

I was debugging something in WordPress, trying to figure out what callback function was applying a change to a filter (in this case a post’s content). To get a list of what functions were hooked into the filter, I threw together a quick helper function and I thought I’d post it here incase anyone else found it useful.

function viper_debug_filter( $filter ) {
	add_filter( $filter, function( $value ) {
		global $wp_filter;

		$filters = array();

		foreach ( (array) $wp_filter[ current_filter() ] as $priority => $functions ) {
			foreach ( (array) $functions as $function => $args ) {
				$filters[$priority][] = $function;

		var_dump( current_filter(), $filters );

		return $value;
	} );

// Pass the filter name here
viper_debug_filter( 'the_content' );

Nothing fancy like excluding itself from the output — it was just a quick and dirty hack. Use it as you see fit.

Debugging WordPress HTTP API Remote Requests

If you’re writing WordPress code that makes remote requests and need to easily debug the requests, here’s some helper code to do it. This requires that you’re using WordPress’s HTTP API which you should already be doing — directly using cURL or other methods is wrong and a great way to make your code not cross-server compatible.

add_action( 'http_api_debug', 'viper_http_api_debug', 10, 5 );

function viper_http_api_debug( $response, $type, $class, $args, $url ) {
	// You can change this from error_log() to var_dump() but it can break AJAX requests
	error_log( 'Request URL: ' . var_export( $url, true ) );
	error_log( 'Request Args: ' . var_export( $args, true ) );
	error_log( 'Request Response : ' . var_export( $response, true ) );

That will log the request URL, the request arguments, and the whole response HTTP_API object to your error log file. The last message one will be pretty long/spammy but it’ll give you headers, the body, and everything else. Since it’s an instance of HTTP_API, you can also do things like this if you want to:

error_log( 'Response Code: ' . wp_remote_retrieve_response_code( $response ) );

Installing PHPUnit On Windows

READ THIS: This guide no longer works due to PHPUnit dropping support for the PEAR installation method. If you’re at this page in order to use PHPUnit for WordPress-related things, then these days I recommend setting up an instance of Varying Vagrant Vagrants which is a pre-built virtual machine configuration for developing using WordPress and includes PHPUnit pre-configured. Otherwise check out the official PHPUnit installation documentation on how to install PHPUnit globally.

I wanted to start contributing to the WordPress unit tests so I needed to install PHPUnit. Turned out it was harder than it might seem (I had a tough time getting it all working) so I thought I’d blog what finally ended up working for me to help save some people some time.

Assuming you already have PHP and MySQL installed, here’s the steps you need to take:

  1. Install PEAR, a dependency for PHPUnit:
    1. Visit in your browser and save the file into your PHP directory. This is the folder where you can find php.exe.
    2. Open an administrator command prompt. Hit your Windows key, type “cmd”, right-click the resulting “cmd.exe” search result, and select “Run as administrator”. Navigate to the folder where you have PHP installed, the same folder where you saved the file in the previous step.
    3. Type the following command to execute the file you just downloaded: php go-pear.phar
    4. After a moment, you should start being prompted for some things. The installer is pretty self-explanatory and I think you want a system installation rather than a local one.
    5. Open the folder where PHP is installed and double-click the PEAR_ENV.reg file that has been created. This allows you to run the pear command from any folder.
    6. Verify PEAR is working by running the command pear version
  2. Install PHPUnit:
    1. Turn on auto_discover in PEAR by typing the following command at the command line: pear config-set auto_discover 1
    2. Download and install PHPUnit by running the following command: pear install
    3. In order to be able to run the phpunit command from any folder, you need to add it to your Windows Path value. Right-click My Computer → Properties → Advanced system settings → Environmental Variables → select “Path” under “System Variables” → Edit → Add a semi-colon (;) and then the full path to your PHP folder onto the end of the value, for example like this: ;D:\Webserver\php
    4. Verify PHPUnit is working by running the command phpunit --version
  3. Set up the WordPress unit tests by following the rest of the steps on the WordPress Core Contributor Handbook now that you have PHPUnit installed.