How to fix UTF-8 filename issues when using wp_handle_upload()

PHP said the file didn’t exist. Except it did.

file_exists() wasn’t working for a file uploaded using wp_handle_upload(). It worked for every other file, except for one provided by a German customer.

I confirmed the following:

  • The file did exist in the correct wp-uploads sub-directory
  • The file had correct permissions
  • The directory and its parents had correct permissions

I was stumped.

Then I renamed the file

I converted indlæsning to indlaesning and it worked. The problem was with UTF-8 characters in the filename.

But how can this be? Let’s see where the file name comes from:

  • _wp_handle_upload() calls
  • wp_unique_filename() to generate a unique file name, which calls
  • sanitize_file_name() to prepare the file name
  • sanitize_file_name() then checks against a list of special characters that are not allowed in file names:
$special_chars = array("?", "[", "]", "/", "\\", "=", "", ":", ";", ",", "'", "\"", "&", "$", "#", "*", "(", ")", "|", "~", "`", "!", "{", "}", "%", "+", chr(0));

This list of characters can be modified using the sanitize_file_name_chars filter, but that seemed more complicated than I wanted.

The sanitize_file_name() function also includes a sanitize_file_name filter, which allows you to modify the name of the file after it’s already been sanitized.

Luckily, WordPress already has a function to convert other UTF-8 characters into Latin equivalents: remove_accents(). I used that to convert the filename into something file_exists() could handle.

Here’s how to fix UTF-8 issues with wp_handle_upload()

That converted the filename from: indlæsning.csv to indlaesning.csv. Note that the æ character got converted to ae.

The result? Finally, file_exists().

Fixing JSON Parse Error in WordPress Plugins

If you write WordPress plugins and make AJAX requests, you may be familiar the dreaded Javascript error: SyntaxError: JSON Parse Error: Unrecognized token '>'

SyntaxError: JSON Parse Error: Unrecognized token '<'

Why? Why!?!

What it means is that the response your code expected is screwed up because a plugin barfed PHP warnings into the admin-ajax.php ventilation system.

When WP_DEBUG is on, admin-ajax.php responses can include junk HTML output from PHP warnings, like:

<br />
<b>Notice</b>:  Undefined offset: 0 in
<b>/wp-content/plugins/im-gonna-break-ur-ajax.php</b> on line
<b>666</b><br />

The fix? Catch exceptions, then exceed expectations

The way to fix this is to wrap the jQuery.parseJSON() function in try/catch. That will make sure that the code doesn’t fully blow up.

try {
  jQuery.parseJSON( response );
} catch( exception ) {
  console.log( exception );
}

That will prevent your code from breaking, but it won’t make your code work.

The cause of the code breaking is the junk HTML at the beginning on the AJAX response. So, what we want to do is:

  1. Check for a valid JSON response
  2. If the JSON is invalid, strips all characters until finding a JSON-style opening of {".
  3. Check the newly stripped string to see if that is valid JSON
  4. If valid, return the JSON. If not, return an error message.

Here’s the code to achieve that:

Let me know what you think, and please fork the Gist if you have any improvements!

How to use your own widget icon in the WordPress Widget customizer

Customize WordPress Widget IconIn developing deeper integration with the Customizer functionality of WordPress, I wanted to use a custom icon for my IDX+ plugin’s widgets.

By default, WordPress defines a list of icons using their dashicons icon set and tries to guess the best icon for your widget based on the CSS class of your widget.

Check out the CSS in customize-widgets.css starting on line 415.

For instance, if your widget’s CSS class contains “music”, “radio”, or “audio”, you will have the format-audio dashicon applied to your widget.

How to change the widget icon

Using Dashicons

Note: In order to choose a new icon, go to the Dashicons website and click on the icon you want to use, then click on the “Copy CSS” link to get the correct CSS content value.

#available-widgets [class*=YOUR_CSS_BASE] .widget-title:before{
    content: "\f217"; /* <-- replace this value */
}

Using your own icon font

#available-widgets [class*=YOUR_CSS_BASE] .widget-title:before{
    font-family: idx-plus!important; /* <-- replace this value */
    content: 'd'; /* <-- replace this value */
}

If you want the icon to change color when it’s hovered over, use the following code:

#available-widgets [class*=YOUR_CSS_BASE]:hover .widget-title:before{
    color: #7da838!important; /* <-- replace this value */
}

I hope this helps!

Help test the Constant Contact API 3.0 plugin beta!

Almost ready.

It’s been a long haul for the new version of the Constant Contact for WordPress plugin. I started working on it before Constant Contact finalized their new API, so let’s just say it has been a major undertaking 🙂 Now I need help getting it ready for release!

The new Constant Contact WordPress plugin has some cool features, such as inline editing of lists and contacts, nicer report layouts, error/activity logging, and much cleaner ways of doing things.

Please help by installing the plugin and reporting issues.

You can download the latest build of the plugin here.

Please help test the plugin and — most important — report issues using this form.

I want to release the plugin in the next three weeks, so please download, install, and submit issues as soon as possible. It would be a huge help.

Are you a developer?

Please help out and contribute on GitHub. Your help will earn you a thank-you link on the plugin’s settings page!

Future plans

Once the new version is released, I plan on allowing this plugin be the connector to Constant Contact for my other integrations (Contact Form 7, Gravity Forms, and Fast Secure Contact Form). That way, other forms can be used instead of the Form Designer and you’d still get all the other functionality of the main API plugin, like viewing and editing contacts.

Thanks for your help!

How to get all downloads in Easy Digital Downloads

Easy Digital Downloads defaults to using 10 results per page when using the get_products() method. You can modify this default using the edd_api_results_per_page filter.

Here’s how to fetch all products at once:

$EDD_API = new EDD_API;

// Force EDD to show all the downloads at once.
add_filter('edd_api_results_per_page', 'modify_edd_api_results_per_page' );

// Get all the EDD products
$products = $EDD_API->get_products();

// Restore sanity to EDD results per page.
remove_filter('edd_api_results_per_page', 'modify_edd_api_results_per_page' );

/**
* Modify the number of results fetched by EDD
* @param int $per_page Previous results per page setting
* @return int New results per page setting. If you have this many, you're in trouble.
*/
function results_per_page($per_page) {
return 99999999; // Yeah, you've got lots of products!
}

How to Add Support for Display Advertising Code in Google Analytics for WordPress

It’s really simple to use Google’s Display Advertising code, so I thought I’d share how.

To enable the new GA features:

  1. Check the “Show Advanced Settings”
  2. Under “Advanced Settings,” check the checkbox for “Host ga.js locally:”
  3. In the text field that appears, enter: //stats.g.doubleclick.net/dc.js
    • Note: The missing http and https is intentional – if your site’s in secure mode, it will use https, otherwise http)
  4. Save your settings!

Testing Translation Function Speeds in WordPress

Speed of memoryAfter reading Pippin Williamson’s post about gettext speed issues, I wanted to learn more. My IDX+ plugin has 815 translatable strings, and I was worried that it was having a performance impact on the plugin.

I created a test that looped through different methods of outputting and printing strings to try and determine their relative speed. WordPress uses different functions for translating strings, as documented in the Codex, and I included __() and _e(), the functions I use the most often.

Here are the results of a 100,000-iteration loop:

  • echo 'Test': 0.1786 seconds
  • $out .= 'Test': 0.2454 seconds (37.4% slower)
  • __('Test'): 0.5301 seconds (196.8% slower)
  • _e('Test'): 0.5639 seconds (215.7% slower)
  • echo __('Test'): 0.5722 seconds (220.4% slower)
  • __('Test', 'test'): 0.5743 seconds (221.6% slower)
  • _e('Test', 'test'): 0.6076 seconds (240.2% slower)
  • echo __('Test', 'test'): 0.614 seconds (243.8% slower)
  • $out .= __('Test', 'test'): 0.6885 seconds (285.5% slower)

“Findings” (non-scientific)

  • Contrary to what I had read, echoing inline was by far the fastest method.
  • Adding a domain (the second parameter) to translation functions slows the functions down a bit.
  • Storing strings in a variable after using __() is slow.
  • All times are well below 1/10th of a second when translating 10,000 strings instead of 100,000.

Conclusion

Although translating 100,000 strings adds half a second processing time, if your site is processing well less than that, you shouldn’t have a problem.

It seems the site Pippin was working on had enough strings to affect the responsiveness of the site, but I would bet that’s not a normal site. I also would bet that the issues the site was having are not because of the translation functions themselves, but the translation plugin the site was running.

I’m going to be using more _e() and less echo __(), but other than that

Toggle WordPress Help Menu

It’s not possible (as far as I know) to currently link directly to a help tab in WordPress. Here’s the jQuery solution I cooked up:


/**
* Toggle the WP help menu tab by linking to the tab id
*
* The anchor must have a `rel` of `wp-help`
*/
$(‘a[rel=”wp-help”]’).click(function() {

// Open the help wrapper if it’s not open yet
if($(‘#screen-meta’).is(‘:hidden’)) {
$(‘#contextual-help-link’).click();
}

// Click on the tab link inside the help wrapper
$(‘#screen-meta a[href*=”‘ + $(this).attr(‘href’).replace(‘#’, ”) +'”]’).click();

// We’re just anchor linking; don’t go anywhere
return false;
});

If the tab’s ID that you pass to `$screen->add_help_tab()` is `example-plugin`, then you could create a link like this: `View the help docs`.

Bradycardia & Cardiac Arrest for WordPress 3.6

Bradycardia is the resting heart rate of under 60 beats per minute….
Wikipedia

WordPress HeartbeatA new feature in WordPress 3.6 is an upgrade to the autosave functionality that’s been around for years. It’s called “Heartbeat” and it makes sure you have valid authentication credentials, aren’t working on the same post as other people, and more. The problem is that (as it is) it slows web pages down to a grinding halt.

Read the active discussion on WordPress.org about this feature – a lot of people are upset about the CPU load it adds.

Note: I don’t recommend doing these changes on every Admin page. Use sparingly.

Slow Down WordPress 3.6’s Racing Heartbeat

Here’s how to slow down the heartbeat from once every 15 seconds (the default) to once every minute (the max allowed by WordPress): Continue reading “Bradycardia & Cardiac Arrest for WordPress 3.6”

Add "Preview" Link to Manage Themes

Get That Preview Link Back!

Ever since WordPress added a Live Preview option to the Manage Themes screen, it’s been frustrating to test a plugin using multiple themes.

Why Live Preview sucks for developers

When using Live Preview, you can’t modify the URL of the page you’re visiting or open the preview in a new window or tab. Live Preview prevents you from viewing multiple themes at once in different tabs.

If you wanted to get the old Preview link back, you had to disable Javascript, then refresh the page, then open the links.  Continue reading “Add "Preview" Link to Manage Themes”

How to Hide or Replace the WordPress Welcome Panel

Updated: now with more in-depth code!

So you want to modify the WordPress Dashboard Welcome Screen

There was a thread on the WPMU website that discusses how to disable the WordPress welcome screen, but the code provided didn’t work, so I figured I’d show how to do it!

The `wp_welcome_panel()` function uses the `show_welcome_panel` user meta setting to determine whether or not to show the welcome panel.  In order to modify this setting, we’re going to add a filter to the `get_user_metadata` filter, which uses the `get_metadata` function.

The following code snippets should be added to your theme’s `functions.php` file.

Disable the dashboard welcome screen…

This will only hide the panel, not replace it with any other content.

add_filter("get_user_metadata", "my_own_welcome_panel", 1, 4);

function my_own_welcome_panel($null, $object_id, $meta_key, $single) {
	if($meta_key === 'my_own_welcome_panel') { return 0; }
}

or Show Your Own Panel

You can replace the WP welcome panel with your own content using this snippet.

add_filter("get_user_metadata", "my_own_welcome_panel", 1, 4);
function my_own_welcome_panel($null, $object_id, $meta_key, $single) {

	// Only work with the show_welcome_panel
	if($meta_key !== 'show_welcome_panel') { return null; }

	// If the user has already said they don't want to see the panel, don't show it!
	$show_panel = get_user_meta( get_current_user_id(), 'my_own_welcome_panel', true );
	if(empty($show_panel)) { return 0; }

	// Echo your HTML or content here, but make sure to have a link like the following:
	?>
	<a class="welcome-panel-close" href="<?php echo esc_url( admin_url( '?my_own_welcome=0' ) ); ?>"><?php _e('Dismiss this Message'); ?></a>
	<?php

	// Return 0 or else the original welcome panel will show as well.
	return 0;
}

// Add the functionality to update the user's settings with whether or not they have closed the panel
add_action('admin_init', 'my_own_welcome_set_welcome_panel');
function my_own_welcome_set_welcome_panel() {
	if ( isset( $_GET['my_own_welcome'] ) ) {
		update_user_meta( get_current_user_id(), 'my_own_welcome_panel', intval($_GET['my_own_welcome']));
	}
}

Major Changes in the WordPress.org Plugin Directory

The new plugin Reviews feature suggests a shifting approach to the WordPress ecosystem.

Reviews: a new tab in town

WordPress.org Reviews TabOn every plugin page, there is now a Reviews tab. This is in addition to the Support tab that WordPress added around August.

Rating a plugin now requires a review

Until now, WordPress reviews were basic: 1-5 stars, with no additional details. You would only need to be signed in and click a star rating. With this change, WordPress.org requires users to be logged in and to write a review with their star rating. This will force users to be more thoughtful on why they rate a plugin a certain way.

You can now reply to reviews. Nice.Each review is now a forum thread: when a review is posted, the plugin author has a chance to reply. This is great for me as a plugin author: I can attempt to  resolve issues and get better plugin ratings. Users are able to modify their reviews and update their star ratings, which adds incentive for plugin authors to address issues with each reviewer. This is smart.

The beginning of higher accountability.

This is one way to add security and stability to the WordPress ecosystem.

I believe WordPress wants to have more tight controls over the plugins listed on the directory.  With over 22,000 plugins, Automattic simply does not have the resources to make sure all plugins are up to snuff.

The WordPress team has taken steps to help users know whether a plugin is good or not:

  • The May update made visible the number of resolved plugin support requests over a time span.
  • Earlier in the year, the website started displayed a banner alerting users when a plugin hadn’t been updated in over two years.
  • In 2011, the website started showing a graph of the plugin star ratings, not just the aggregated star rating. This helped visualize the plugin’s ratings.

WordPress as a platform.

Matt Mullenweg spoke at a WordCamp recently about his vision for auto-updating WordPress where users wouldn’t have to manually upgrade the software. His vision is of WordPress as a hassle-free platform, and I bet that reducing the variables added by troublesome plugins or themes is a high priority.

WordPress 3.5, currently in beta, introduces a new feature (emphasis mine):

You can browse and install plugins you’ve marked as favorites on WordPress.org, directly from your dashboard.

This feature, in concert with more in-depth reviews, marks a shift from a directory of plugin downloads to more of a WordPress “App Store” mentality: when you are logged in to your account, you can easily find and download your favorite plugins. The directory, armed with better ratings and review, will show higher-rated plugins first. All from inside WordPress instead of on the WordPress.org website.

This reviews implementation is a big next for the plugin directory, and is likely the first  step of many. I look forward to seeing what is planned for the directory, as well as the WordPress platform as a whole.


Notes as a Plugin Developer

  • On each plugin page, you can grab an RSS feed of the reviews, which will be helpful for responding to review comments. This is functionally similar to the plugin Support forum.
  • I really, really like this change. It will help good plugins get discovered.
  • Plugin authors can now respond to their critics! Re: Marco Arment.

Feature Request: Per-Version Ratings

Each review prominently displays the date of the review. I’m hoping that WordPress segment reviews on a per-version basis, like what Apple does in their App Store. There would be two charts: ratings for all versions, and ratings for the current version.

Create a Custom Error Page for "Error establishing a database connection"

Error establishing a database connection

Here’s how to make a custom database error page for WordPress.

If your site’s all set up and you see “Error establishing a database connection,” that’s an immediate “oh crap” situation.

Hostgator.com, the company that hosts this website, has had some issues recently, and I’ve seen that screen a little too often.

If you want to define a custom “Error establishing a database connection” screen, add a file to your /wp-content/ folder named db-error.php. That will be loaded instead of that stupid message. Check out SEODenver.com’s db-error.php.

A Good Idea for SEO

If you want to prevent search engines from indexing your site while it’s down, add <meta name="robots" content="noindex, nofollow" /> to your page’s `<head>`. You sure don’t want Google caching your error! Continue reading “Create a Custom Error Page for "Error establishing a database connection"”

Generate a Link to Activate a Plugin in WordPress

Here’s another specialized plugin development tip!

If you want to create a link to activate a plugin, you need to know the path of the plugin file. Let’s use Akismet for this example.

$path = 'akismet/akismet.php';
$link = wp_nonce_url(admin_url('plugins.php?action=activate&plugin='.$path), 'activate-plugin_'.$path);

The `$link` URL will be something like http://yoursite.com/wp-admin/plugins.php?action=activate&plugin=akismet%2Fakismet.php&_wpnonce=f97dabdf9

How to Hard-Code a UA String for the Google Analytics for WordPress Plugin

If you want to define a Google Analytics “UA String” while using Yoast Google Analytics plugin for WordPress.

Add the following to your theme’s `functions.php` file:

add_filter( 'option_Yoast_Google_Analytics', 'custom_ua_string_filter');

function custom_ua_string_filter($options = array()) {
	$options['uastring'] = 'UA-########-#';
	$options['manual_uastring'] = true;
	return $options;
}

For users of WordPress Multisite, this will allow you to pre-configure new blogs with the same UA string.

Enable Shortcodes for Gravity Forms Field Descriptions

To enable shortcodes inside your Gravity Forms form description, field labels and descriptions, you need to add the following code to your theme’s `functions.php` file:


add_filter(‘gform_pre_render’, ‘walker_do_shortcode_gform_description’, 10, 2);

function do_shortcode_gform_description(&$item, $key) {
$item = do_shortcode($item);
}

function walker_do_shortcode_gform_description($form, $ajax) {

$form[‘description’] = do_shortcode($form[‘description’]);
array_walk_recursive($form[‘fields’], ‘do_shortcode_gform_description’);

return $form;
}

Merge Settings Into an Array in WordPress

Arrays Merging

I found people are coming to this site (to an unrelated article) looking for a way to merge settings into an array.

You’re looking for `wp_parse_args()`

The main function for WordPress to do this is `wp_parse_args()`. You likely want this function.

Learn more about `wp_parse_args()`

Also consider `shortcode_atts()`

This is used for parsing shortcode options. It only supports defined arguments.

Learn more about `shortcode_atts()`

Simple Way to Get Plugin Status in WordPress

Active plugin volcano.

I have previously written on how to determine if a widget is active. This is helpful for widgets, but not for plugins.

WordPress has a couple of different functions that help you determine plugin status. They are both located in wp-includes/plugin.php

  • `validate_plugin()` spits out an error if the plugin file does not  exist or has an invalid header. This lets you know that the file is there.
  • `is_plugin_inactive()` lets you know if the plugin is not active (using the `is_plugin_active()` function)

A function to get plugin status

Using these two functions, I put together a one-size-fits-all function `get_plugin_status()`. Continue reading “Simple Way to Get Plugin Status in WordPress”