Safe Signup Form

Description

Safe Signup Form is a WordPress Plugin that will forward a form submission to an email address, while preventing most automated attacks.

To do this it leverages Elliot Back’s WP Hashcash — an elegant anti-spam engine that uses javascript to determine if the form is submitted by a robot or a Web browser.

An administration page provides three options for handling submissions identified as spam:

  1. Delete spam submissions.
  2. Flag spam submissions (and forward them anyway).
  3. Forward without flagging.

The basic plugin offers a simple name and email form, but the php can be easily modified to incorporate any number of fields.

You can download Safe Signup Form here.

Safe Signup Form uses XHTML compliant code and has been tested in WordPress 2.7 through 2.9.1, MSIE 7 and 8, Firefox 3 and 4, and Safari 3.

Installation

  1. Upload ddf-signup.php to the wp-content/plugins directory of your WordPress install.
  2. Activate the plugin through the Plugins menu in WordPress.
  3. View the Secure Form - Signup page under Plugins to set options for presentation, spam handling, validation, and other options. The Secure Form - Signup page also provides statistics on the number of spam vs. total submissions.
  4. To add a form to a page either create a template with the php function: <?php ddfs(); ?> or enter the shortcode [ddfs] in any post or page content.

IMPORTANT: If you are using WP Super Cache, changes you make using the Secure Form - Signup page may not appear. If this happens, edit and republish the page that presents the form.

Frequently asked questions

Q. I can’t get the form to send me an email.

A. The form should pick up the default admin email associated with your install of WordPress. To change it go to the Safe Signup Form page under Plugins in the WordPress Admin tool (you may need to log in as “admin”). You can then change the “forwarding email” value.

Since the forwarding email is generated by a script it may be blocked by your email server or filtered as junk mail by your email program. Check any spam or junk mail folders at the local and server level.

Q. Can I automatically forward an email confirmation to the user?

A. Not yet. I did not include automatic email confirmation because of the security implications — it allows a form to become a conduit for spamming third party addresses. The HashCash technology stops most robotic spam attacks, but human spammers could take advantage. I may add email confirmation as a option to a future version.

Q. Can I add additional fields?

A. The only way to add fields is to directly edit the plug-in PHP. If you know HTML and a little PHP this isn’t too difficult.

There are three places in the code where a new form field is defined or processed.

For example, let’s say you wanted to add a “Nickname” text field before the email field.

First, in the ddfs_install() function, add the new field to the $options['error-rules'] array. This defines how the field is validated.

// Rules for form validation - server side
// 'r' means required
// 'o' means optional
// 'e' means value must be a valid email
// a duplicate key requires a duplicate entry (as in 'ddfs-repeat-email')
$options['error-rules'] = array(
'ddfs-name' => 'r',
'ddfs-nickname' => 'o', // New field is set as "optional"
'ddfs-email' => 'e',
'ddfs-repeat-email' => 'ddfs-email'
);

Second, also in the ddfs_install() function, you may optionally add a label for the new field to the $options['forward-labels'] array. The appearance of the field in this array ensures that it is included in the form email notification.

// Labels and fields for form elements to be
$options['forward-labels'] = array(
'Name' => 'ddfs-name',
'Nickname' => 'ddfs-nickname', // New field is assigned to the "Nickname' label
'Email' => 'ddfs-email'
);

Third, in the ddfs_form_display() function, enter the new field’s HTML markup in the $form array. This displays the field on the page as part of the whole form. Make sure the label, field name, and $_POST value all match. For the id field I use the convention f- plus the field name.

/* Read form */
function ddfs_form_display() {
$form = array(
// Error message markup
'error-msg' => '',
// Rules for form validation - client side
'error-field' => '<input id="f-ddfs-rules" name="ddfs-rules" type="hidden" value="f-ddfs-name:r f-ddfs-email:e f-ddfs-repeat-email:d:f-ddfs-email" />',
// Default form markup
'ddfs-name' => '<p><label for="f-ddfs-name" class="required">' . __('First Name', 'ddfs') . '</label><input type="text" name="ddfs-name" id="f-ddfs-name" maxlength="50" tabindex="10" value="' . htmlentities($_POST['ddfs-name']) . '" class="f" /></p>',
'ddfs-nickname' => '<p><label for="f-ddfs-nickname" class="required">' . __('Nickname', 'ddfs') . '</label><input type="text" name="ddfs-nickname" id="f-ddfs-nickname" maxlength="50" tabindex="11" value="' . htmlentities($_POST['ddfs-nickname']) . '" class="f" /></p>', // New field HTML markup
'ddfs-email' => '<p><label for="f-ddfs-email" class="required">' . __('Email Address', 'ddfs') . '</label><input type="text" name="ddfs-email" id="f-ddfs-email" maxlength="50" tabindex="15" value="' . htmlentities($_POST['ddfs-email']) . '" class="f" /></p>',
'ddfs-repeat-email' => '<p><label for="f-ddfs-repeat-email" class="required">' . __('Repeat Email Address', 'ddfs') . '</label><input type="text" name="ddfs-repeat-email" id="f-ddfs-repeat-email" maxlength="50" tabindex="16" value="' . htmlentities($_POST['ddfs-repeat-email']) . '" class="f" /></p>'
);
return $form;
}

In each of these cases, if you add fields to the end of the array, don’t forget to add a comma after ddfs-repeat-email (or ddfs-email in the second case). Then, make sure the last field in each array is not followed by a comma.

IMPORTANT: After editing the plugin PHP and saving it to the plugins folder, you must deactivate and reactivate it to see your changes. This is done under Plugins in the WordPress Admin tool (you may need to log in as “admin”). After that, you may also need to edit and republish the page that presents the form.

WARNING: When you deactivate and reactivate the plugin you will have to reenter any options you set on the Secure Form - Signup page.

Q. How do I change the appearance of the labels, fields and messages?

A. You can create the formatting you want by editing the “Custom Styles” option at the bottom of the Secure Form – Signup page. The default CSS is:

div.ddf label { padding-right: 0.5em; }
p.intro { font-style: italic; }
p.error { color: #ff0000; }
p.success { font-weight: bold; }

To stack labels over the fields, change div.ddf label to:

div.ddf label { display: block; }

To align fields to the right of the labels, you can try something like:

div.ddf label { display: block; float: left; width: 12em; }

Experiment with CSS and you should be able to get the format you like.

Have a question? Please use the comment form and I will do my best to respond.

Changelog

1.1

  • Updated code to use localization (translation) functions for both admin and output.
  • Corrected the “Error-spam flag” and “Error-spam cancel” fields to allow HTML tags.
  • Added a “Compliant XHTML” admin option that places plugin javascript and CSS into the header of each page rather than into the body of the local page.
  • Corrected a bug with the form action value that caused problems with calling the plugin from a template outside of The Loop

Upgrade Notice 1.1

This upgrade corrects several minor bugs and provides an option for compliant XHTML output. Use it if you want to call the plugin from a template outside of The Loop, desire XHTML compliance, want to format error messages, or want to localize the plugin.

Test the form

You can try out the form below. This is a dummy version and does not email to a live account. Try it with and without javascript enabled on your browser to see the spam response.

Please provide the information requested below. We will use your email only to communicate with you. We will not share it with anyone else for any reason.

Donate

Safe Signup Form is free, but any small donation is appreciated.

Comments

Hi. Integrated your form but it doesn’t send e-mail. Not sure what to check…

Posted by by Gene on May 4, 2009 at 5:59 pm  

The form should pick up the default admin email associated with your install of WordPress. If it doesn’t, or if you want to change it, go to the Safe Signup Form page under the Plugins option in the WordPress Admin tool (you may need to log in as “admin” to see it). You can then change the “forwarding email” value.

There is the possibility that since the email is generated by a script that it is being blocked by your email server or filtered as junk mail by your email program.

Posted by by Henry on May 4, 2009 at 8:02 pm  

Hi Henry

I installed your form and like what I see so far, however, it doesn’t send an email confirmation to the new user. I tested it out and received an email (as the admin) announcing the new user, but the new user email did not receive the Confirmation email.

Any suggestions?
Thanks

Posted by by Matt on May 31, 2009 at 5:18 pm  

This is where the form is.

Posted by by Matt on May 31, 2009 at 5:20 pm  

I did not include automatic email confirmation because of the security implications — it allows a form to become a conduit for spamming third party addresses. The HashCash technology stops most robotic spam attacks, but human spammers could take advantage.

Still, the risk of this is probably pretty small. I will add auto confirmation as an option for the next version.

Posted by by Henry on June 1, 2009 at 10:27 am  

Hi Henry

We have uploaded the sign up plugin to our wordpress blog

On para 4 you said the following:

To add a form to a page either create a template with the php function: or enter the shortcode [ddfs] in any post or page content.

Could you please advice how can we create this template, what is the code and where to we add it?

Thanks so much for your assistance

Sharon Gilor

Thanks for

Posted by by Sharon on August 4, 2009 at 6:59 am  

Hi Sharon,

The easiest method for adding the form is to use the shortcode.

Simply create a new page or blog post through the WordPress Admin interface. Then, in the WordPress editor, add the shortcode [ddfs] wherever you want the form to appear. When you publish the page or post the shortcode is replaced by the full form.

For information on creating a custom template for a WordPress Page, see this article in the WordPress Codex. A discussion of Page Templates starts about halfway down.

If you place the Safe Signup Form php function in a template it appears any time you use that template to create a page.

To summarize — the shortcode is designed to be used within the WordPress editor and can be added to any page or post. The php function is designed to be used within a custom template within your WordPress theme.

Posted by by Henry on August 4, 2009 at 8:54 am  

Hi Henry

Thanks so much for your prompt and detailed response.

I will try it out and see how it works

Best Regards
Sharon

Posted by by Sharon on August 4, 2009 at 3:21 pm  

Great plugin, but it is wreaking havoc with W3C XHTML 1.0 Transitional validation. The validator doesn’t like the free-floating < and & in the php. I tried encoding those, but that broke the functionality. Any tips? I’m using the form for the email sign-up in the sidebar of this site: work in progress site

Posted by by Kelly on September 24, 2009 at 12:20 pm  

Hi Kelly,

Thanks for the comment. I do place Javascript calls in the HTML which won’t validate. There is a WordPress method for loading Javascript code into a page header that gets around this (Elliot Back uses it for WP Hashcash). The problem is that this approach loads the Javascript into every page and/or post on the site. It also doesn’t initialize the Javascript functions until the page finishes loading.

I’m a believer in valid code, but weighing the costs and benefits I decided to group the form and the Javascript together — this makes the form more portable and more responsive. For better or worse, this technique is becoming more common on the Web with the spread of AJAX applications.

I will look at adding an option to use a valid approach in the next version.

Posted by by Henry on September 25, 2009 at 8:49 am  

How do I add additional fields?
I want to add a multi-line comment field. Can I do this?
Is there a way to have the data entry area of the fields line up?

Posted by by Martin on December 24, 2009 at 3:48 pm  

great plugin? one question: is it possible to format the plugin so the name of each text box appears above the box so the alignment of boxes are symmetrical?

Posted by by steven adjmi on December 27, 2009 at 10:42 am  

Hi Martin,

The only way to add fields is to directly edit the plug-in PHP. If you know HTML and a little PHP this isn't too difficult.

There are three places in the code where a new form field is defined or processed. If, for example, you want to add a form field named “ddfs-msg”, you would do the following:

After Line 75: Insert the name of the field and a flag for how it is validated — generally either 'r' for required or 'o' for optional. For example:

'ddfs-msg' => 'o'

After Line 81: Insert a label that identifies the field value in the forwarded email. For example:

'Message' => 'ddfs-msg'

After Line 420: Insert the HTML code for the field: For example:

'ddfs-msg' => '<p><label for=”ddfs-msg”>' . __('How can we help you?', 'ddfs') . '</label><textarea name=”ddfs-msg” id=”f-ddfs-msg” tabindex=”18″>' . htmlentities($_POST['ddfs-msg']) . '</textarea></p>'

(In each case, remember to add a comma to the line above so you don't break the array).

By repeating these steps you can add as many fields to the form as you want.

After editing the form, you need to upload it to your plugins folder. Rename the old one so you can recover it if necessary. Then you need to to deactivate and reactivate the plugin.

Posted by by Henry on December 28, 2009 at 10:59 am  

Hi Steven (and Martin)

You can create the formatting you want by editing the “Custom Styles” option at the bottom of the Secure Signup Form options page. The default CSS is:

div.ddf label { padding-right: 0.5em; }

To stack the labels over the form elements, change this to:

div.ddf label { display: block; }

To line up the fields to the right of the labels, you can try something like:

div.ddf label { display: block; float: left; width: 12em; }

Experiment with CSS and you should be able to get the format you like.

Posted by by Henry on December 28, 2009 at 11:15 am  

Just curious if you can help with the email notification. I have input my email address into the admin back end and I filled out the form 3 times but I am not receiving anything. I have check my inbox and junk mail. Just curious if there is a way to hard code the email into the php.

Thanks, great plug in.
Kevin

Posted by by Kevin Hester on January 10, 2010 at 6:03 pm  

Hi Kevin,

Since the forwarding email is generated by a script it may be getting screened out by your ISP before it gets to you. If your ISP has a webmail feature you could check there for a spam folder.

If you want to hardcode in an email address, a quick and dirty way is to directly assign the $mailto variable in the code. For example:

$mailto = “henry@henrywoodbury.com”;

After editing the plugin file, you need to upload it to your plugins folder. Rename the old one so you can recover it if necessary. Then you need to to deactivate and reactivate the plugin.

Posted by by Henry on January 10, 2010 at 8:33 pm  

I implemented the form and it worked brilliantly. However since then I have amended CSS and added new javascript files. Now it doesn’t seem to work. I’ve even tried to add it to one of the default templates and it still won’t work. I have reinstalled it also.

Sorry if this sounds like a moan as its an excellent little plugin.

Posted by by Rick on January 11, 2010 at 7:06 am  

Hi Rick,

The only thing I can think of is that your new CSS or Javascript has created a naming conflict. The Plugin reserves a Javascript function named ddfs_hc() and looks for unique element ids that start with f-ddfs-.

If you have a URL you can post I can take a quick look at the source.

Posted by by Henry on January 11, 2010 at 12:34 pm  

Hi Henry

Url is http://www.webmanchester.com/curious/

Thanks

Posted by by Rick on January 12, 2010 at 5:28 am  

Hi Rick,

Sorry, I couldn’t find anything. I tested this page with the js libraries you use and the form still worked. I also tested it on WordPress 2.9.1 successfully. I didn’t see anything in the CSS or XHTML that would conflict with the form.

Posted by by Henry on January 12, 2010 at 3:01 pm  

Thanks for checking. It looks as though the code is not triggering the following:

Line 521: if (isset($_POST['ddfs-flag'])) {

Don’t know if that helps. Could it be anything to do with permalinks?

Posted by by Rick on January 12, 2010 at 5:30 pm  

Fixed it!

Changed Line 561:

$ddfs .= “\n”;

To:

$ddfs .= “\n”;

Posted by by Rick on January 13, 2010 at 6:30 am  

Last post seems to have stripped out code. Basically I deleted ” . get_permalink() . ” from line 561.

Sorry for clogging up the comments.

Posted by by Rick on January 13, 2010 at 6:31 am  

Not to worry. I appreciate the feedback. I found a thread on WordPress that indicates that get_permalink() may not always be predictable, so I will follow this up.

Posted by by Henry on January 13, 2010 at 10:16 am  

Henry,

Great plugin! I have tried several times to remove the duplicate email entry. I removed what I thought was the relevant code, but it still appears. I have read the code 3 times and cannot figure out what I am missing. If you can help, that would be much appreciated.

Thanks!

Damien

Posted by by Damien Hoffman on February 10, 2010 at 1:58 pm  

Hi Damien,

There are three places in the code where the repeat email address is processed:

Line 86: ‘ddfs-repeat-email’ => ‘ddfs-email’
Line 486: ‘error-field’ => ‘<input id=”f-ddfs-rules” name=”ddfs-rules” type=”hidden” value=”f-ddfs-name:r f-ddfs-email:e f-ddfs-repeat-email:d:f-ddfs-email” />’,
Line 442: ‘ddfs-repeat-email’ => ‘<p><label for=”f-ddfs-repeat-email” class=”required”>’ . __(‘Repeat Email Address’, ‘ddfs’) . ‘</label><input type=”text” name=”ddfs-repeat-email” id=”f-ddfs-repeat-email” maxlength=”50″ tabindex=”16″ value=”‘ . htmlentities($_POST['ddfs-repeat-email']) . ‘” class=”f” /></p>’

You need to delete lines 86 and 442 (and the commas at the ends of line 85 and 441 so as not to break the arrays). On line 486, delete just the ‘ f-ddfs-repeat-email:d:f-ddfs-email’ portion of the line.

Once you do this you should be able to upload the edited version of the plugin and reactivate it. You may need to also republish any page that references it if you are using a caching engine.

Posted by by Henry on February 10, 2010 at 3:01 pm  

Thanks, Henry! I greatly appreciate the support for your plugin!

All the best,

Damien

Posted by by Damien Hoffman on February 10, 2010 at 9:25 pm  

Henry,

Sorry to bother you. One last question:

How should I alter the custom CSS section if I’d like 1) to center the submit button, and 2) stack the input fields so they are in line with one another (seems like more space is needed between the Name label and input to get the inputs in line).

THANKS!

Damien

Posted by by Damien Hoffman on February 10, 2010 at 10:02 pm  

Hi Damien,

The submit button is in a paragraph with a class of “ddf-right”. You can use that class to center its contents:

p.ddf-right { text-align: center; }

To line up the input fields to the right of the labels, you can give the labels that precede them a set width. Try something like:

div.ddf label { display: block; float: left; width: 12em; }

Experiment with CSS and you should be able to get the amount of space you like.

Posted by by Henry on February 11, 2010 at 10:18 am  

Thanks, Henry. You run a great site!

Posted by by Damien Hoffman on February 12, 2010 at 12:10 pm  

Excellent plugin Henry. Saved me a lot of time.

Posted by by Sanat on February 24, 2010 at 3:52 am  

Thanks a lot for this wonderful plugin.. I’ve modified the styling and implemented it at hayden5media.com in the mailinglist box at the bottom of the page.

Keep up the great work

Posted by by Sanat on April 6, 2010 at 6:04 am  

I would like to add additional fields – but they are not showing up. My code is as follows:

// Rules for form validation – server side
// ‘r’ means required
// ‘o’ means optional
// ‘e’ means value must be a valid email
// a duplicate key requires a duplicate entry (as in ‘ddfs-repeat-email’)
$options['error-rules'] = array(
‘ddfs-name’ => ‘r’,
‘ddfs-email’ => ‘e’,
‘ddfs-repeat-email’ => ‘ddfs-email’,
‘ddfs-address’ => ‘o’,
‘ddfs-city’ => ‘o’,
‘ddfs-zip’ => ‘o’,
);

// Labels and fields for form elements
$options['forward-labels'] = array(
‘Name’ => ‘ddfs-name’,
‘Email’ => ‘ddfs-email’,
‘Address’ => ‘ddfs-address’,
‘City’ => ‘ddfs-city’,
‘Zip’ => ‘ddfs-zip’,
);

// Set default form code
$options['form-defaults'] = ddfs_form_display();
$options['form'] = ddfs_form_display();
$options['form'] = ddfs_form_display();
$options['form'] = ddfs_form_display();
$options['form'] = ddfs_form_display();

I am assuming the last part is wrong but I’m not sure how to amend to make the fields show up. Thank you.

Posted by by Jackie on May 25, 2010 at 1:41 pm  

I realized it was supposed to be at form_display function further down so added this:

/* Read form */
function ddfs_form_display() {
$form = array(
// Error message markup
‘error-msg’ => ”,
// Rules for form validation – client side
‘error-field’ => ”,
// Default form markup
‘ddfs-name’ => ” . __(‘First Name’, ‘ddfs’) . ”,
‘ddfs-email’ => ” . __(‘Email Address’, ‘ddfs’) . ”,
‘ddfs-repeat-email’ => ” . __(‘Repeat Email Address’, ‘ddfs’) . ”,
‘ddfs-address’ => ” . __(‘Address’, ‘ddfs’) . ”,
‘ddfs-city’ => ” . __(‘City’, ‘ddfs’) . ”,
‘ddfs-zip’ => ” . __(‘Zip’, ‘ddfs’) . ”,
);
return $form;
}

they are still not showing up.

Posted by by Jackie on May 25, 2010 at 2:00 pm  

Hi Jackie,

One small point — on each of the arrays you are modifying, make sure not to end the last item with a comma. That implies another, nonexistent, entry.

Your later message is the correct approach, but I don’t see HTML markup. Is that implied? Anyway, the $form array outputs HTML, so if you want to see input fields, the HTML needs to be coded into those lines. You can use the current ddfs-name or ddfs-email line as a model.

Finally, you may just be running into caching issues. After uploading and reactivating the revised plugin, use the WordPress Admin interface to go to the page that presents the form and republish it.

Posted by by Henry on May 25, 2010 at 2:27 pm  

whoops! the text area read my HTML and stripped the tags. The HTML is as follows –

/* Read form */
function ddfs_form_display() {
$form = array(
// Error message markup
‘error-msg’ => ”,
// Rules for form validation – client side
‘error-field’ => ”,
// Default form markup
‘ddfs-name’ => ” . __(‘First Name’, ‘ddfs’) . ”,

‘ddfs-email’ => ” . __(‘Email Address’, ‘ddfs’) . ”,

‘ddfs-repeat-email’ => ” . __(‘Repeat Email Address’, ‘ddfs’) . ”,

‘ddfs-address’ => ” . __(‘Address’, ‘ddfs’) . ”,

‘ddfs-city’ => ” . __(‘City’, ‘ddfs’) . ”,

‘ddfs-zip’ => ” . __(‘Zip’, ‘ddfs’) . ”,
);
return $form;
}

not sure if it’s a caching issue – I did republish and they still aren’t showing up.

Posted by by Jackie on May 25, 2010 at 7:24 pm  

ok, sorry – it happened again – I can’t seem to post the HTML here.

Posted by by Jackie on May 25, 2010 at 7:24 pm  

Hi Jackie,

I have updated the “Q. Can I add additional fields?” section of the FAQ with an example. Take a look. Hopefully it helps.

Posted by by Henry on May 27, 2010 at 3:08 pm  

Thanks. I did exactly that – still no new fields. I am pretty baffled.

Posted by by Jackie on May 28, 2010 at 10:02 am  

Hi!

Your plugin is wonderful and your documentation makes things very easy to implement!

However, I am having the same problem as Jackie – the new fields just aren’t showing up – and I just can’t figure it out!!

I have put your plugin into a text widget and it works beautifully… but it just displays without the additional field!

Everything seems to be correct. In fact I have copied your “nickname” example into the file. I thought that it may be a caching issue and have tried viewing it on a number of different computers. But still nothing!!

Any ideas?

Thanks!!

Posted by by Ilana on June 29, 2010 at 4:06 pm  

Hi Ilana,

Thanks for your kind words.

I’ve retested this process and realized that I didn’t specify an additional final step — After making the changes to the plugin and reloading it to your WordPress install, you need to deactivate and reactivate the plugin. You may also need to edit and republish the page that presents the form. Sorry for the confusion. I will update the documentation.

Posted by by Henry on June 30, 2010 at 10:50 am  

It worked! Thank you! Thank you!

You may also want to tell folks that when they deactivate/activate the plugin, any options that they may have changed on the Secure Form – Signup page (under Plugins) will revert back to the default settings.

Thanks again Henry!!

Posted by by Ilana on June 30, 2010 at 1:23 pm  

Good point. I’ve added a warning to the instructions.

Posted by by Henry on June 30, 2010 at 3:22 pm  

Post a comment

Powered by WP Hashcash