Category Archives: Platforms

Prevent contact form spam in WordPress with Contact Form 7 and Akismet

Preface

If you’re running WordPress and have a contact form on your website, there’s a good chance you’re using Contact Form 7. You can get away with using it as-is for a while, but as time goes on, spambots begin to find their way into your inbox.

At that point you have two options. You can deal with the spam via your:

  1. Website– prevent messages from ever being submitted.
  2. Inbox– tune your spam filter to delete those messages.

It seems logical to try and stop the messages as early as possible.

Most people would resort to something like CAPTCHA now, but I’m personally not a fan of it. I believe in keeping the user experience in tact for as long as I possibly can.

Enter Akismet, a service that can pretty reliably identify post comments containing spam. Luckily, what’s good for comments is also good for emails. It makes sense, too, because from a spambot’s perspective, both are submittable forms.

Continue reading

Bash script to mirror directory and database of website between servers

Preface

When you have a site that’s an on-going project, and you’re using a development, staging, and production server configuration, time and time again you’ll have a need to mirror the  production site content with your other environments.

Previously, this either meant to manually (FTP) or semi-manually (rsync) update the files, export the database, and in the case of WordPress MU, update certain records in the database. While the entire act isn’t hard, it has a zero-fun factor.

I put some time aside to write a small bash script that could automate this for multiple sites with just two commands. The script could definitely be improved, but it’s functional and gets the job done nicely, but I’m always open to suggestions and improvements.

I’ll go through the entire script, and if you find it useful, you can adapt it to meet your needs. Any variables or data you may need to change, will be highlighted in red below the code box.

You can find the entire code in a Gist. Note that there are two versions. One for server to server, the other for server to localhost. We’ll discuss the server edition below.

Table of Contents

  1. Program Skeleton
  2. Server Environment
  3. Production/Local Server Variables
  4. Program Arguments
  5. Display Functions (page 2)
  6. MySQL Functions
  7. Main Functions (page 3)
    1. Download Files
    2. Export Database
    3. Upload Files
    4. Import Database
  8. Run Functions (page 4)
    1. Run Synchronize
    2. Run Update
    3. Run
  9. Run Program (page 5)

Continue reading

Prevent WordPress from automatically purging trash from custom post type

Preface

WordPress has a constant called EMPTY_TRASH_DAYS that it automatically sets to 30. What that means is that WordPress will automatically delete all posts, pages, custom post types, etc, that have been in the trash for 30 or more days.

1
2
3
4
5
6
7
8
// wp-includes/default-constants.php
 
function wp_functionality_constants( ) {
    ...
    if ( !defined( 'EMPTY_TRASH_DAYS' ) )
        define( 'EMPTY_TRASH_DAYS', 30 );
    ...
}
// wp-includes/default-constants.php

function wp_functionality_constants( ) {
	...
	if ( !defined( 'EMPTY_TRASH_DAYS' ) )
		define( 'EMPTY_TRASH_DAYS', 30 );
	...
}

Whenever you trash a post, WordPress creates a meta field called _wp_trash_meta_time containing the time it was trashed.

1
2
3
4
5
6
7
// wp-includes/post.php
 
function wp_trash_post($post_id = 0) {
    ...
    add_post_meta($post_id,'_wp_trash_meta_time', time());
    ...
}
// wp-includes/post.php

function wp_trash_post($post_id = 0) {
	...
	add_post_meta($post_id,'_wp_trash_meta_time', time());
	...
}

WordPress has a daily event scheduled…

1
2
3
4
// wp-admin/admin.php
 
if ( !wp_next_scheduled('wp_scheduled_delete') && !defined('WP_INSTALLING') )
    wp_schedule_event(time(), 'daily', 'wp_scheduled_delete');
// wp-admin/admin.php

if ( !wp_next_scheduled('wp_scheduled_delete') && !defined('WP_INSTALLING') )
	wp_schedule_event(time(), 'daily', 'wp_scheduled_delete');

…that will run a function called wp_scheduled_delete to permanently delete all expired posts.

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
// wp-includes/functions.php
 
function wp_scheduled_delete() {
    global $wpdb;
 
    $delete_timestamp = time() - ( DAY_IN_SECONDS * EMPTY_TRASH_DAYS );
 
    $posts_to_delete = $wpdb->get_results($wpdb->prepare("SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_wp_trash_meta_time' AND meta_value < '%d'", $delete_timestamp), ARRAY_A);
 
    foreach ( (array) $posts_to_delete as $post ) {
        $post_id = (int) $post['post_id'];
        if ( !$post_id )
            continue;
 
        $del_post = get_post($post_id);
 
        if ( !$del_post || 'trash' != $del_post->post_status ) {
            delete_post_meta($post_id, '_wp_trash_meta_status');
            delete_post_meta($post_id, '_wp_trash_meta_time');
        } else {
            wp_delete_post($post_id);
        }
    }
    ...
}
// wp-includes/functions.php

function wp_scheduled_delete() {
	global $wpdb;

	$delete_timestamp = time() - ( DAY_IN_SECONDS * EMPTY_TRASH_DAYS );

	$posts_to_delete = $wpdb->get_results($wpdb->prepare("SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_wp_trash_meta_time' AND meta_value < '%d'", $delete_timestamp), ARRAY_A);

	foreach ( (array) $posts_to_delete as $post ) {
		$post_id = (int) $post['post_id'];
		if ( !$post_id )
			continue;

		$del_post = get_post($post_id);

		if ( !$del_post || 'trash' != $del_post->post_status ) {
			delete_post_meta($post_id, '_wp_trash_meta_status');
			delete_post_meta($post_id, '_wp_trash_meta_time');
		} else {
			wp_delete_post($post_id);
		}
	}
	...
}

Continue reading

How to use PHP variables in jQuery in WordPress

Preface

Often times you need access to server-side data in your JavaScript. Most people accomplish this in one of three ways:

  1. Echo out JavaScript in PHP
  2. Place data in HTML attributes for jQuery to grab
  3. Make ajax request to PHP

I won’t go into the pros and cons of each, but there is actually a fourth way that’s much leaner and cleaner, but unfortunately not a lot of people know about it. In one word: wp_localize_script.

Here is a step by step of how it works.

Continue reading