Eliminate Unused WordPress Plugins

Consider this post a public service announcement.

It’s a common misconception that if a plugin is deactivated in WordPress, that you are immune from performance or security issues.

On it’s face, this is not true, and you are risking the internet with this mentality!

Take last year’s Timthumb debacle, for instance. Many themes include Timthumb for dynamic resizing of images. Sometimes plugins do. When those themes or plugins are not activated, you are correct in assuming WordPress is not loading them. What you are failing to see is that their existence on the filesystem provides a vector of attack for someone wanting to exploit a system-level exploit.

Not to say Timthumb is insecure. Old versions are. I still don’t like it for other reasons, like performance. Simply using it as an example.

But if you decide to not use a plugin or a theme, delete the damn thing so it’s presence doesn’t even exist. In the case of Timthumb, the security flaw wasn’t a WordPress exploit. It was a “PHP directly interacting with the system” exploit and it would be there anywhere else regardless of CMS. It could exist on a static site.

And it’s not just your site at risk. Fuck your site. What if that flaw in whatever flawed code existed woke up a botnet? Then everyone is at risk. I’m at risk. You and your silly site are at risk. Joe the plumber’s site is at risk. Thoretically.

So be responsible. Delete unused code from your site. Remove themes you don’t use. Delete plugins you don’t use.

And when I say delete, I mean, permanently delete. Don’t just deactivate.

The Internet thanks you.

Update: This is not a verdict on any plugin or theme. To my knowledge, most are perfectly fine. Just clarifying that this is a “just in case” precaution.

10 Things You Need to Know About WordPress 3.4

query.php

WordPress 3.4 is around the corner. It’s currently beta4 which means a Release Candidate or three will be needed before it drops officially. If you want to test what’s out there now, the way to do that is through SVN. As usual, however, pre-release WordPress is not supported. As usual, however, I have been running trunk throughout the entire development cycle without any problems.

Before I get into the guts of WordPress 3.4, I want to point you to a resource which highlights some of the thinking that is going into the development, now and in the future, of how WordPress is built. Andrew Nacin sent an email to the “hackers” mailing list discussing object-oriented development that informs the thinking of the core developers now that WordPress supports PHP 5.2 and true object-oriented programming.

While it may be over the head of non-developer types, the gist is that now that we (used loosely) can write code smarter, we’re working our way in that direction. Some of the code in WordPress has existed for “generations” of versions and is bulky and inefficient. With new tools at our fingertips, we can begin to approach the idea of refactoring some of this code in better ways. Backwards compatibility is always retained, however, in 99 out of 100 times. WE ARE NOT DRUPAL!

Without further adieu, however, let’s get into what you can expect in the new version of WordPress.

Embed Tweets with oEmbed

Since version 2.9, WordPress has supported a technology called oEmbed that, simply put, has allowed the inclusion of rich media in content in a very simple way. Simply paste a YouTube link on a new line, and WordPress turns it into a properly sized video. No embed code needed. Same for Vimeo, Flickr, Scribd and more. The entire list can be found on the Codex. Now, however, Twitter is supported. Simply place the URL of a tweet on it’s own line and… bam, you have this:

Query Efficiency Improvements

The common bottleneck for all WordPress users are database queries and data “munging”… that is, what WordPress does with data when it’s returned from the database. The query that brings in all the necessary content necessary to render a page used to look like this:

1
SELECT * FROM wp_posts WHERE...

This has been how the query has worked for years. Really since the beginning of WordPress. And while, in theory that works (and it does, again it has for years), the core reality of this approach is that all the data in the posts table matching the criteria in the WHERE clause is more data than is needed, thus causing potential performance problems.

The new approach is simple and elegant. The first database query simply fetches a list of post IDs that fit the criteria provided in the WHERE clause.

1
SELECT ID FROM wp_posts WHERE...

This approach means the amount of data in memory and floating around WordPress is concise and compact. PHP doesn’t have to work harder to traverse arrays or objects… it is simply a smaller list of data.

But what about the other data? We need the other data! Yes, in fact we do. But since WordPress has an object cache, much of this data is in the object cache. We don’t need to retrieve it from the database.

The second step is to look to the object cache for posts with IDs matching any of the IDs in the first dataset. Anything we can’t find is followed with a second query to get all the information matching the non-matched IDs using MySQL’s IN() function:

1
SELECT * FROM wp_posts WHERE ID IN(10, 34, 78);

By changing how SQL and object caching is used, WordPress 3.4 finds new efficiencies. In the original ticket, developers were observing 2-3x speed performance improvements. I’ll drink to that.

Theme Customizer

Non-technical WordPress users will love the new Theme Customizer. Otto has a great write-up on this new feature. His video is above. The key takeaway from this new feature is that is possible now to customize a great number of things in a theme  from right within WordPress. On the fly. with a live preview.

Change your title, tagline, background color, image and more with a click of a mouse. I can see this being used to create child themes in the future, but for now, it manages settings that are already in WordPress (and accessible in other areas of the WordPress Admin) on the fly. The best way to really appreciate this feature is via Otto’s video above. Related: The best way to leverage this as theme developers is outlined in great detail in his post…

Bundled ‘Touch’ Support

We live in a touchy-feeley world. And by that, I mean mobile. Specifically iOS and Android. In WordPress 3.3, we saw adaptive design come to portions of WordPress. Adaptive design, for the uninitiated, is a technology that elegantly resizes a website to adapt to the the screen it is rendered on. It is a way for developers to create a single experience that works on desktop/laptop browsers as well as mobile interfaces with arbitrary resolutions.

As mobile continues to lead the charge in today’s web, WordPress 3.4 has bundled the jQuery UI Touch Punch library that will give front-end developers more tools to work with in making a website mobile-friendly. Simply include the library via wp_enqueue_script() and now your element has the .draggable() method available. This method enables “drag and drop” support that was previously unavailable and the one major caveat is that it does not support Windows 7/7.5 phones due to limitations in the IE9 browser.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?php
class My_Awesome_Plugin {
    public function __construct()
    {
        $this->hooks();
    }
    public function hooks()
    {
        add_action( 'wp_head', array( $this, 'js' ) );
    }
    public function js()
    {
        wp_enqueue_script( 'jquery' );
        wp_enqueue_script( 'jquery-ui' );
        wp_enqueue_script( 'jquery-touch-punch' );
        wp_print_scripts();
        ?>
        <script>
        jQuery(document).ready(function(){
            jQuery('#element').draggable();
        });
        </script>
        <?php
    }
}
$my_awesome_plugin = new My_Awesome_Plugin;

HTML in Captions

Red Sox

Photo by Kyle McCluer and used under Creative Commons. Some Rights Reserved.

I’m trying to rotate between developer tools and user tools in this article, so at this time, I’d like to point out a simple yet important frustration in previous versions of WordPress. When you upload an image and use the media uploader to then insert an image, you have the option of writing a caption. Sadly, it was impossible to include HTML in previous WordPress versions.

Often times, linking the source of a photo is welcome and, possibly depending on the usage restrictions on a photo, required. Before, the only way to do that was to set a link in the media uploader and then the photo would be linked. Now, in WordPress 3.4, you can include basic HTML in your captions as I have done above.

XML-RPC Improvements

XML-RPC. The thing that allows the WordPress apps for Android, BlackBerry and iOS to function. The thing that allows offline editors to function by remotely communicating with WordPress through a public-facing API.

XML-RPC is a venerable technology that is based mainly on the Metaweblog API invented a decade ago. WordPress has supported this iteration of XML-RPC as well as the Movable Type XML-RPC and Blogger XML-RPC APIs for a long, long time. However, WordPress has also extended the Metaweblog API and added it’s own methods along the way.

No more. Instead of band-aiding a solution on top of a limited set of methods intended for blogging only, WordPress 3.4 includes a brand new WordPress XML-RPC API designed to support all the rich features that have evolved since WordPress started focusing on CMS-style features. It incorporates all the methods introduced before as extensions to Metaweblog such as wp.getOptions, wp.getMediaItem, etc and introduces new ones such as wp.getPostTypes and wp.getTaxonomies to name just a few.

It’s important to note that only WordPress products are likely to ship with support for this new API at first, but old capabilities will still exist and function, as backwards compatibility is ensured. As API clients add support for WordPress’ new capabilities, we will see more common usage.

Internationalization (i18n) Improvements

For international WordPress users, WordPress 3.4 continues the tradition of enhancing your experience. As we in the community have stated many times, i18n is incredibly important to WordPress growth and development. In discussing this article with someone inside of the WordPress core community, I am told 2 out of every 3 WordPress users are non-American. Additionally, I am told that 40% of WordPress installations are non-english.

That’s Huge!

The running list of i18n changes in WordPress 3.4 is here. Some notable changes include:

  • Comma translation. While most languages use a comma as a separater (or delimiter), some do not. This enhancement is useful for languages like Chinese and Arabic that don’t use a comma.
  • Single-Double quote translation. It’s odd to think, but some languages like Hebrew, actually have distinct meanings for jots that are punctuation marks in an English world.
  • Default Timezones. It’s possible now to override the timezone WordPress uses in a translation. This, as you can imagine, is important when a language is largely spoken in one region in a single timezone.

Page Template Handling

For theme developers looking to put more organization around their theme file structure, a new change has gone in that has both an obvious, front-facing benefit as well as a background benefit. Now, you can place any page template inside a subdirectory of a theme. So you can now have a /pages/ subdirectory and segregate all of your extraneous one-off or multi-use page templates to that folder (or any folder). WordPress will identify all page templates in the theme root or in a subdirectory of a theme root and make them available for pages to use.

The background benefit of this comes in a new WP_Theme API that is lighter weight, more efficient and handles all the work for you. It’s important to note that most developers will never need to use this API and it is largely considered an “internals” thing.

In relation to the i18n improvements discussed earlier, the headers in these page templates are also now translatable. Simply include a Text Domain: and Domain Path: header in your style.css where the textdomain is the defined textdomain for translations (i.e. twentyeleven) and the Domain Path is the path relative to the stylesheet directory (i.e. the proper place the theme is regardless of if it’s a parent theme or a child theme) where the POT file is (/langs). I don’t want to get too deep into this as Andrew Nacin, the architect of this feature, plans to put out a field guide going into detail. Stay tuned to that.

Custom Header API

For a few versions now, WordPress has supported two functions add_custom_header_image() and add_custom_background(). These two functions have added new menus for designating header and background images to the Appearances menu.

WordPress 3.4 introduces a new API for dealing with custom headers and backgrounds and introduces new flexibility in terms of image sizes, etc. The two functions above have been deprecated (which means they’ll work for awhile but will ultimately go away, so use the new techniques) and replaced with new theme support. If you recall from previous version, we use the add_theme_support() function to, well, add support for a feature in a theme. To integrate the new stuff, include these lines in your theme functions.php:

1
2
3
<?php
add_theme_support( 'custom-header' );
add_theme_support( 'custom-background' );

Both function calls can take a second argument which must be an array of presets, but it’s entirely optional. To omit the second argument renders behavior as we’ve known it for some time. To include it allows theme developers to designate designate parameters for both elements, that can then be customized by the end user.

For custom headers, you may include defaults along these lines (gregariously stolen from the Codex):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
$defaults = array(
    'default-image'          => '',
    'random-default'         => false,
    'width'                  => 0,
    'height'                 => 0,
    'flex-height'            => false,
    'flex-width'             => false,
    'default-text-color'     => '',
    'header-text'            => true,
    'uploads'                => true,
    'wp-head-callback'       => '',
    'admin-head-callback'    => '',
    'admin-preview-callback' => '',
);
add_theme_support( 'custom-header', $defaults );

Likewise, for custom background defaults you might have this:

1
2
3
4
5
6
7
8
9
<?php
$defaults = array(
    'default-color'          => '',
    'default-image'          => '',
    'wp-head-callback'       => '_custom_background_cb',
    'admin-head-callback'    => '',
    'admin-preview-callback' => ''
);
add_theme_support( 'custom-background', $defaults );

Bonus

Did you know?

  • PHP end of file closing PHP tags are now removed. Those are these – ?> Why is this important? Including the closing tag means that if there is any white space at the end of a file, PHP is likely to break. Omission means that PHP assumes a close tag at the end of the file and whitespace can’t corrupt. Personally I’ve argued for this in the past. The main opponent must have been in a coma when this was slipped through by other core developers.
  • Distraction Free Writing, first introduced in WordPress 3.2 is now supported by all custom post types.
  • The theme installer now has infinite scroll which is just kind of pretty aesthetic thing. It also defaults to keyword searches when you’re browsing for a new theme on the WordPress Theme repository.
  • Internal functions and classes now output “rtl”, “ie7″, “ie8″, etc as classes for browser targetting.

TUTORIAL: Using WordPress’ Ajax API

WordPress has tons of APIs to do tons of things. It really does. One of the cool ones that I’ve been using a lot lately, has been around for a bit. It’s the Ajax API. Sure, you could write your own Ajaxy thing but why do that when WordPress lets you do it all very simply.

This tutorial will show you how to replicate the functionality that is presented in the “Like” button at Facebook. It assumes that you have WordPress set to require users to be logged in to take such actions. It wouldn’t make much sense for someone to not be logged in for such functionality. Obviously, you could do something else with Ajax (polls? Loading new content?) that doesn’t have the same assumption, but in this case… we’re assuming a user is logged in and the $current_user global is set.

Getting Started

Let’s start with the basic PHP class (you do write good object-oriented code, right?)

1
2
3
4
5
6
7
8
class My_Like_Button {

    function __construct()
    {
    }
}

$my_like_button = new My_Like_Button;

This code is just a basic skeleton that provides a constructor (the __construct() method, which I’ll use later. It also instantiates a new My_Like_Button object and assigns it to the $my_like_button variable for use in the global scope. Obviously, you can use whatever strikes your fancy for the class name or the global variable.

Building the HTML for the Like Button

Next, we need the basic HTML structure that will be used in our theme for the Like button. For the sake of simplicity, I’m not providing any CSS, but feel free to do as you wish. We need to add this as a new method in our class.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function like_button()
{
    if( !is_user_logged_in() )
        return false;
       
    global $current_user;
       
    $html = '<form action="" method="post">
        <input type="hidden" name="like_post_id" id="like_post_id" value="'
. get_the_ID() .'">
        <input type="hidden" name="like_user_id" id="like_user_id" value="'
. $current_user->ID . '">
        <input type="button" name="like_this_post" id="like_this_post" value="Like" />
    </form>'
;
    return $html;
}

This form provides two hidden form fields using get_the_ID() and the $current_user object. Having done this (and after ensuring there is a logged in user), we can now drop this into our theme in the Loop as a template tag:

1
<?php echo $my_like_button->like_button(); ?>

Sending the Ajax Request with jQuery

This is useless by itself. We need something to handle the Ajax. But before we get there, we need to understand how Ajax works within the WordPress context.

All requests must go to wp-admin/admin-ajax.php. Forget the confusion about why you would send a front-end Ajax request to the back-end. You just do.

On the back-end, you’ll have to define functions that will hook into the Ajax API to let WordPress know how to handle the request. More on that in a minute. Let’s build some jQuery to send this to admin-ajax.php.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
function js()
{
    wp_enqueue_script( 'jquery' );
    wp_print_scripts();
    ?>
    <script>
    jQuery(document).ready(function(){
           
        jQuery('#like_this_post').click(function(){
            var like_post_id = jQuery('#like_post_id').val();
            var like_user_id = jQuery('#like_user_id').val();
           
            jQuery.post(
                '<?php echo get_option('siteurl') . '/wp-admin/admin-ajax.php' ?>',
                {
                    action      : 'register_like',
                    user_id     : like_user_id,
                    post_id     : like_post_id,
                    _wpnonce    : '<?php echo wp_create_nonce('nonce-register_like'); ?>',
                },
                function(response) {   
                    alert(response);
                }
            );
               
        });
    });
    </script>
    <?php
}

This is just a PHP function that we can use to throw some jQuery (using the .post() method for our Ajax call) into the head. Note the nonce. You must include this for security. Additionally, you must have an action set. The action is used by WordPress to route the Ajax request.

Finally, we’re passing two extra pieces of data – user_id which is the WordPress user ID and the post_id which is the WordPress post ID of the current $post object inside the Loop. Both of these are supplied in the hidden form fields we created earlier.

Let’s add a new method for hooks and call it in our constructor, so that hooks are executed when the object is instantiated:

1
2
3
4
5
6
7
8
9
function __construct()
{
    $this->hooks();
}
   
function hooks()
{
    add_action( 'wp_head', array( $this, 'js' ) );
}

Supplying the Ajax Handler

Having hooked the jQuery into WordPress, we now need something on the other end to handle the request and return something back to our page. For this, let’s create a method called handle_like().

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
function handle_like()
{
    global $wpdb;
    $user_id = (int) $_POST['user_id'];
    $post_id = (int) $_POST['post_id'];
       
    if( !is_user_logged_in() )
        return false;
       
    if( !wp_verify_nonce( $_POST['_wpnonce'], 'nonce-register_like' ) )
        die( 'Go away, asshole!' );
       
    /*
        Here is where we do some sort of database operation to associate
        the Like of the given post with the user who performed the action
       
        Make sure you check for errors. In order to return data, you must
        echo something that the originating page can see. True or false
        only makes sense on this page and not back there.
           
        Typically, you'd output some sort of JSON, XML or plain text.
    */

    $meta_id = add_post_meta( $post_id, 'user_liked', $user_id );
    if( !$meta_id )
        echo "Like not recorded";
    else
        echo "Like recorded";
    exit;
}

In this method, it’s important that all data be sanitized to avoid security problems. I’m performing the most basic of data security here by casting the $_POST variables for the users ID and the post ID to integers.

We’re also checking to make sure the user is logged in. This is why using the built in WordPress Ajax API is actually kind of important. If you build your own Ajax handler, there’s no way to reliable tie in to WordPress to use other APIs like the User API.

Finally, make sure you verify the nonce so you know the request is coming from a legitimate source.

The three security procedures I just listed will largely prevent SQL Injection, ensure authenticated users and eliminate the possibility of Cross Site Request Forgery (CSRF) and generally should be used in all WordPress plugin development.

Simply though, the above method takes the post ID, the user ID and creates a new record in the postmeta table. On success, it will print a success method readable by the original sending page and vica versa on failure.

Note: You must use die() or exit() at the end of the method to make sure the Ajax response exits properly.

Tying the Handler into WordPress

Now that we have a handler method to do our bidding, we need to make sure WordPress knows about it so it routes Ajax requests to the proper place. To do this, we leverage the wp_ajax_{$action} hook.

Remember earlier, while building the jQuery Ajax request, I mentioned that an action POST variable had to be set? WordPress looks to this variable to create a dynamic hook that we can use our new Ajax callback to hook into.

1
add_action( 'wp_ajax_register_like', array( $this, 'handle_like' ) );

Because our action in the js() method was set to register_like, the hook WordPress creates dynamically is wp_ajax_register_like and we can use that to hook our Ajax handler onto.

Wrapping it all Together

Easy right? Use jQuery to send data, wp-admin/admin-ajax.php to receive the Ajax request and pass it on to an appropriate handler function, and send data back to the original page. On the receiving end, you can use normal means to handle the returned data as you wish.

You can download the full code used here at Github.