adi_contact – Form field validation & spam prevention

This plugin is used in conjunction with zem_contact_reborn to provide the following functionality:

  • submitted field combination check
  • submitted field content validation
  • anti-spam measures

Once installed, a collection of tags are available:

Use the above tags within a <txp:zem_contact> ... </txp:zem_contact> container. A full example of usage is provided at the end.

A number of additional CSS classes are automatically applied to help with styling.


Form field combinations (adi_contact_combo)

Sometimes certain combinations of form fields are required from users, for example:

  • fill in at least one of “Likes”, “Dislikes”, “Other comments”
  • if “Phone number” is filled in then “Best time to call” is also required
  • if “Region” is Other, then “Other Region” field is required

For example, to make sure the user fills in at least one field in a specified list:

<txp:zem_contact>
  ...
  <txp:zem_contact_textarea name="likes" label="Likes" required="0" />
  <txp:zem_contact_textarea name="dislikes" label="Dislikes" required="0" />
  <txp:zem_contact_textarea name="comments" label="Other comments" required="0" />
  <txp:adi_contact_combo names="likes,dislikes,comments"
    restrict="min" number="1" />
</txp:zem_contact>

Or if an extra field has to be filled in:

<txp:zem_contact>
  ...
  <txp:zem_contact_text name="phone" label="Your phone number"
    required="0" />
  <txp:zem_contact_text name="when" label="When should we call you?"
    required="0" />
  <txp:adi_contact_combo names="phone" require="when" />
</txp:zem_contact>

And to specify a required field depending on the value of a supplied field:

<txp:zem_contact>
  ...
  <txp:zem_contact_select name="region" label="Where do you live?"
    list=",UK,France,Germany,Other" />
  <txp:zem_contact_text name="region_other" label="If Other, then where?" required="0" />
  <txp:adi_contact_combo names="region" value="other" require="region_other"
    message="Where else do you live?" />
</txp:zem_contact>

You can also generate custom error messages by using required="0" in the standard ZCR tags and required="1" in adi_contact_combo. For example:

<txp:zem_contact>
  ...
  <txp:zem_contact_text name="name" label="Name" required="0" />
  <txp:adi_contact_combo names="name" required="1" message="Don't be shy!"/>
</txp:zem_contact>

No real magic here – required="1" is actually the equivalent of restrict="equal" number="1".

adi_contact_combo – attributes

names="name list"

- comma separated list of field names that are of interest. Default = “” (none).

value="value"

- If value specified then additional fields of interest will only be flagged if the supplied name field has this value. Default =”“ (required/restricted fields not dependent on value). Used in conjunction with require and restrict.

restrict="restriction"

- defines a minimum (min), a maximum (max), or an exact number (equal),

number="integer"

- number of fields, used in conjunction with restrict.

case_sensitive="boolean"

- defines whether to take notice of case when checking value. Default = “0” (case-insensitive).

require="name list"

- comma separated list of field names that are required (or if used with restrict then of additional interest), depending on the presence or values of fields in names list.

required="boolean

- the specified field is required (useful for creating custom error messages). Default = “0” (not required).

message="text"

- alternative error message (see below for list of placeholders).

checkbox

- this attribute is no longer valid (use adi_contact_checkboxes tag instead).


Form field validation (adi_contact_validate)

This enables the contents of fields to be validated, for example to check that a phone number field has been filled in properly:

<txp:adi_contact_validate names="home_phone" type="phone" />

Or to check that fields have been filled in the same (e.g. for double checking supplied email addresses):

<txp:adi_contact_validate names="email1,email2" type="equal" />

adi_contact_validate – attributes

names="name list"

- comma separated list of field names that should be validated. Default = “” (none).

type="validation"

- the type of validation that is required:

  • alpha – alphabetic characters
  • alphanum – alpha-numeric characters
  • integer – digits only
  • numeric – a number (e.g. +0123.45e6 is a number)
  • phone – phone number (i.e. 0-9 + – . , () xX space)
  • url – a URL (with or without “http://”)
  • custom – use in conjunction with pattern
  • equal – two or more field values must be the same
  • base64 – base64 encoded

allow_whitespace="boolean"

- allow whitespace (i.e. space, tab, newlines etc) in addition to that specified in type. Default = “0” (No).

pattern="pattern string"

- a pattern that will be dropped straight into preg_match. Used in conjunction with type="custom". Default = “” (none).

message="text"

- alternative error message.


Spam prevention (adi_contact_spam)

This will prevent email header injection and stop emails that contain links (which is, after all, what spammers want to send you).

By default adi_contact_spam will check all fields, so if you want users to send you links then use the exclude attribute:

<txp:zem_contact>
  ...
  <txp:zem_contact_text name="website" label="Your website URL" />
  <txp:adi_contact_spam exclude="website" />
</txp:zem_contact>

adi_contact_spam – attributes

names="name list"

- comma separated list of field names that should be checked. Default = “” (all submitted fields).

exclude="name list"

- comma separated list of field names that should NOT be checked. Default = “” (none).

detect_mail_headers="boolean"

- detect the presence of to:, from:, bcc:, multipart, cc:, Content-Transfer-Encoding:, Content-Type:, Mime-Version: and flag as spam if found. Default = “1” (Yes).

detect_link_tags="boolean"

- detect the presence of [url, http, www, href and flag as spam if found. Default = “1” (Yes).

allow_www="boolean"

- allow the presence of www and do not flag as spam. Default = “0” (No).

message="text"

- alternative error message.


Error messages, labels and styling (adi_contact_labels & the ‘message’ attribute)

The ‘message’ attribute

The adi_contact tags will generate standard error messages in English and are placed in the same list as the standard zem_contact error messages. The messages can be customised by using the message="" attribute:

  • alter the standard message
  • translate the standard message into other languages
  • use [NAMES] (‘names’ attribute), [REQUIRE] (‘require’ attribute) & [NUMBER] (‘number’ attribute) placeholders

For example, if adi_contact_spam finds a link, say, in a field called Comments then the standard error message will be:

Link detected in “Comments” ([url, http, www, href not allowed).

But you can customise the error message:

message="Nice try! No spam allowed in [NAMES]."

to produce:

Nice try! No spam allowed in Comments.

adi_contact_labels – attributes

name1="label string 1" name2="label string 2"

- the labels to use in adi_contact error messages.

Important: The adi_contact_labels tag MUST be placed in the page/form before other adi_contact tags – otherwise your label strings won’t be picked up.

Example:

<txp:adi_contact_labels phone="Phone number" when="When to call"
  likes="Likes" dislikes="Dislikes" comments="Comments" />

Notes:

  • a label specified with adi_contact_labels does not have to match the actual label used in the form
  • labels specified with adi_contact_labels are only used in adi_contact error messages
  • the error messages will use labels in the following order of preference:
    • label specified in adi_contact_labels
    • form label retrieved from zem_contact (but only if a field has been filled in & submitted)
    • the field name (with first letter in upper case)

Checkboxes (adi_contact_checkboxes)

Checkboxes have to be identified as such, so that adi_contact can process them properly. However this is only required if you are using adi_contact to process checkbox fields.

adi_contact_checkboxes – attributes

names="name list"

- comma separated list of field names that are checkboxes. Default = “” (no checkboxes to be processed by adi_contact).

Important: The adi_contact_checkboxes tag MUST be placed in the page/form before adi_contact_combo tags – otherwise checkbox validation won’t work.

Example:

<txp:zem_contact_checkbox name="Orange" label="Orange" required="0" />
<txp:zem_contact_checkbox name="Apple" label="Apple" required="0" />
<txp:zem_contact_checkbox name="Banana" label="Banana" required="0" />
  ...
<txp:adi_contact_checkboxes names="Orange,Apple,Banana" />

Javascript (adi_contact_javascript)

adi_contact will normally automatically insert javascript into the page, so that the error case styling classes can be added as appropriate. However, in the situation where zem_contact is implemented as two forms i.e. with show_input="0" and show_error="0" then <txp:adi_contact_javascript /> must be explicitly present in both forms. Make sure it is placed before all other adi_contact tags.


Styling

Classes are automatically added to form label and input/textarea elements when errors are found.

A class of adi_contact_error is always added, together with the following:

adi_contact_comboadi_contact_combo_error, zemRequirederrorElement

adi_contact_validateadi_contact_validate_error, errorElement

adi_contact_spamadi_contact_spam_error, errorElement


The Full Monty Example

The following is an example of a user feedback form:

<txp:zem_contact to='me@example.com' subject='Feedback form example'>

  <p>Please fill in the form:</p>

  <!-- the feedback form presented to the user -->
  <txp:zem_contact_select name="title" label="Title" list=",Mr,Mrs,Miss" />
  <txp:zem_contact_text name="name" label="Name" />
  <txp:zem_contact_radio name="sex" label="Male" group="Gender" />
  <txp:zem_contact_radio label="Female" />
  <txp:zem_contact_checkbox name="general" label="General enquiry" required="0" />
  <txp:zem_contact_checkbox name="sales" label="Sales enquiry" required="0" />
  <txp:zem_contact_checkbox name="technical" label="Technical enquiry" required="0" />
  <txp:zem_contact_checkbox name="feedback" label="Feedback" required="0" />
  <txp:zem_contact_email name="email" />
  <txp:zem_contact_text name="phone" label="Your phone number" required="0" />
  <txp:zem_contact_select name="region" label="Where do you live?" list=",UK,France,Germany,Other" />
  <txp:zem_contact_text name="region_other" label="If Other, then where?" required="0" />
  <txp:zem_contact_text name="when" label="When should we call you?" required="0" />
  <txp:zem_contact_textarea name="likes" label="Likes" required="0" />
  <txp:zem_contact_textarea name="dislikes" label="Dislikes" required="0" />
  <txp:zem_contact_textarea name="comments" label="Other comments" required="0" />

  <txp:zem_contact_submit label="Send feedback" />

  <!-- specify labels to be used in error messages -->
  <txp:adi_contact_labels phone="Phone number" when="When to call" comments="Comments" />

  <!-- identify which fields are checkboxes -->
  <txp:adi_contact_checkboxes names="general,sales,technical,feedback" />

  <!-- "region_other" field required if "region" field is set to other -->
  <txp:adi_contact_combo names="region" value="other" require="region_other" message="Where else do you live?" />

  <!-- male or female required -->
  <txp:adi_contact_combo names="sex" required="1" message="Male or Female?" />

  <!-- at least one of "general,sales,technical,feedback" required -->
  <txp:adi_contact_combo names="general,sales,technical,feedback" restrict="min" number="1" message="What type of enquiry?" />

  <!-- "comments" required for "general,sales,technical" enquiries -->
  <txp:adi_contact_combo names="general,sales,technical" require="comments" />

  <!-- at least one of "likes,dislikes" required for "feedback" enquiry -->
  <txp:adi_contact_combo names="feedback" require="likes,dislikes" restrict="min" number="1" />

  <!-- if "phone" supplied then "when" required as well; include custom error message -->
  <txp:adi_contact_combo names="phone" require="when" message="You've given me a [NAMES] but I need to know [REQUIRE] too" />

  <!-- validate the phone number -->
  <txp:adi_contact_validate names="phone" type="phone" />

  <!-- check for spam but allow user to send simple "www." URLs -->
  <txp:adi_contact_spam allow_www="1" />

</txp:zem_contact>

Notes:

  • the <txp:adi_contact_labels /> tag is placed before the other adi_contact tags (only the labels for phone, when & comments are specified here because they’re required to be different from the actual form labels)
  • the <txp:adi_contact_checkboxes /> tag is placed before the adi_contact_combo tags
  • a name has been explicitly defined for every zem_contact_* field, and these are then used in the adi_contact_* tags – if a name is not specified then it is automatically generated in the markup & the adi_contact tags won’t be able to match them up
  • a checkbox that has been ticked is taken to be “filled in”, so value="yes" is not required

Additional information

Support and further information can be obtained from the Textpattern support forum. A copy of this help is also available online. More adi_plugins can be found here.

Version 0.5 - Download (Uncompressed) Support