I’ve been using Stanley Yeah’s great WP Post Thumbnail plugin for quite some time now. It provides an easy to use interface for cropping and editing post thumbnails for use in your custom WordPress themes. He’s recently released a beta version of the plugin for testing with the latest 2.8 release of WordPress.
UPDATE: It appears this is broken again when upgrading to WordPress version 2.9.2. Currently working on a fix.
The Problem
I was developing a custom WordPress theme for a client in a shared hosting environment when I ran into a problem with the WP Post Thumbnail (WPPT) plugin. When editing a post in the WordPress admin, the loading spinner image next to the Preset1 tab never disappeared. It just kept spinning and spinning. To troubleshoot, I enabled the console panel in Firebug to examine the AJAX request/response data. As is common in the AJAX paradigm, the response is sent back to the requesting page as JSON. But the Firebug console reported a JSON parse error when trying to evaluate the AJAX response.
WPPT makes use of PHP’s json_encode() and json_decode() functions to encode/decode data. The JSON extension is bundled with PHP >= 5.2.0 by default, but a lot of shared hosting environments have older versions of PHP where these functions are unavailable. The WPPT plugin accounts for this and bundles its own versions of the functions to be used should native PHP functions be unavailable. In wp-content/plugins/wp-post-thumbnail/wppt.php, it checks for the presence of the JSON extension and includes it’s own file if it doesn’t exist:
if ( !function_exists('json_encode') )
require_once( dirname(__FILE__) . '/includes/json.php' );
Unfortunately, the functions bundled with this plugin do not produce 100% valid JSON and you’ll still get the parse error. So what to do?
A Real Replacement For json_encode() and json_decode()
For a true json_encode() equivalent, I turned to PHP PEAR. There is a Services_JSON package available. You can donwload this package and get the source code or just copy and paste the code here. Simply replace the code in the wp-content/plugins/wp-post-thumbnail/json.php file with this code. But you’re not done yet. Keep reading.
Avoid Conflicts With Other WordPress Plugins
There are other WordPress plugins that use this code for their own json_encode() substitutes. Twitter Tools is one. If you have Twitter Tools installed and include this code with the WPPT plugin, your whole WordPress installation will break because you’ll be declaring the classes Services_JSON and Services_JSON_Error in two places which isn’t allowed. To avoid this, I namespaced the class names in the json.php file by prepending Wppt_ to the class names.
Do a search and find all instances of these lines:
class Services_JSON
class Services_JSON_Error
Replace with these respectively:
class Wppt_Services_JSON
class Wppt_Services_JSON_Error
Final Step
Add the following code at the end of the wp-content/plugins/wp-post-thumbnail/includes/json.php file so that when the WPPT plugin calls json_encode() or json_decode(), these functions will be called:
function json_encode($data) {
$json = new Wppt_Services_JSON();
return( $json->encode($data) );
}
function json_decode($data) {
$json = new Wppt_Services_JSON();
return( $json->decode($data) );
}
That should do it. The WPPT plugin should work without any errors. One thing to note is that any subsequent plugins that rely on the PHP’s JSON extension will also use the functions you just defined above. I’m willing to live with this since the Services_JSON package is vetted by virtue of being part of PEAR. Should the client’s web host decide to version up PHP, all plugins will start using the native JSON functions and mine will simply fade into obscurity.