Last updated: 31/01/2012 1:11pm

New website!

Check out the new website for a new or updated article on this topic:
www.balbuss.com/implementing-mathspamprotection/

Create a MathSpamProtection field

05-12-2010
MathSpamProtection is fully translated in v2.4, but not yet supported by the SpamProtectionManager. Part of the reasons I wanted to delve into this was the fact that I was suddenly for whatever obscure reason, sort of blacklisted by Mollom. This is no longer the case, but it made me thingking that I wanted other options as well. Recaptcha is not  on my list because of language issues.

Using the SpamprotectionManager

Using the SpamProtectionManager makes MathSpamProtection available for the UserForms module as well. For the SpamprotectionManager to support MathSpamProtection you need two classes: The MathSpamProtectorField class that generates a TextField-like field for the MathSpamProtection, and the MathSpamProtector class that will implement the field. Next you need to point the SpamprotectionManager to the right protector class in mysite/_config.php.

The two class-files can be located anywhere - mysite/code would be fine, but you might need to do a /?flush=1 on the page. 

MathSpamProtectorField

The MathSpamProtectorField, extends the SpamProtectorField and is loosly based on the TextField. Validation in turn is based on how it's done in the EmailField. Reminder: look into Ajax forms...

MathSpamProtectorField.php:

<?php
/**
 *  MathProtectorField: basically a TextField copy with a
*  fixed maxlength setting, that validates against the
*  given MathSpamProtection setting
*
 *  20-09-2010
 *  @author: M. Bloem, Balbus Design
 */

class MathSpamProtectorField extends SpamProtectorField {

  /**
   * Creates an input field, class="text" and type="text"
   * with a 'fixed label' to which the current
   * MathSpamProtection question is added.
   */

  function __construct($name, $title = null, $value = "", $form = null){

    // add the MathSpamProtection question
    if (!empty($title)) $title .= ': ';
    $title .= MathSpamProtection::getMathQuestion();

    parent::__construct($name, $title, $value, $form);
  }


  /*
   *  These values are copied from the TextField class,
   *  where only the maxlength and size settings are different
   */

  function Field() {
    $attributes = array(
      'type' => 'text',
      'class' => 'text' . ($this->extraClass() ?
$this->extraClass() : ''),
      'id' => $this->id(),
      'name' => $this->Name(),
      'value' => $this->Value(),
      'tabindex' => $this->getTabIndex(),
      'maxlength' => 2,
      'size' => 30
    );
    return $this->createTag('input', $attributes);
  }


  /*
   *  Validation
   *  @TODO does this work for Ajax forms?
   */

  function validate($validator){

    $this->value = trim($this->value);
    if(!$this->value ||
       !MathSpamProtection::correctAnswer($this->value)) {
      $validator->validationError(
        $this->name,
        _t(
          'MathSpamProtectionField.VALIDATION',
          'Please enter a correct answer to this question (numbers only).'
          ),
        'validation'
      );
    }
  }
}

MathSpamProtector

This is the class that returns the MathProtectorField to be included in the form:

MathSpamProtector.php:

<?php
/**
* MathProtector: The protector implements MathSpamProtection
* by returning the required FormField (the MathProtectorField)
*
* 20-09-2010
* @author: M. Bloem, Balbus Design
*/

class MathSpamProtector implements SpamProtector {

 /**
  * Return the Field that we will use in this protector
  *
  * @return MathProtectorField
  */

  function getFormField($name = 'Math', $title = '',
                        $value = null, $form = null,
                        $rightTitle = null) {
    $title = _t(
      'MathSpamProtector.SPAMQUESTION',
      'Spam protection question'
    );
    return new MathSpamProtectorField(
      $name, $title, $value, $form, $rightTitle
    );
  }


 /**
  *  Function required to handle dynamic feedback of the system.
  *  if unneeded just return true
  *
  * 
@return true   */
  public function sendFeedback($object = null, $feedback = ""){
    return true;
  }
}

Enable MathSpamProtection

In mysite/_config.php

// enable MathSpamProtection
SpamProtectorManager::set_spam_protector('MathSpamProtector');

The ContactForm

Adding MathSpamProtection to a form should be a piece of cake. For the UserForms you just have to add a SpamProtection field in the CMS. On the ContactPage mentioned above, adding the spam protector goes like this:

In BalbusContactPage.php:

function ContactForm() { 
  ...
 
  $form = new Form(
   $this, 'ContactForm', $fields, $actions, $validator
  );

  // enable MathSpamProtection
  if(class_exists('SpamProtectorManager')) {
    SpamProtectorManager::update_form($form);
  }

  // now return the Form object for the template
  return $form;
}

jQuery validation - temporary solution

This only refers to my ContactPage: in the frontend I try to avoid the use of Prototype in favour of jQuery. For the time being I just added the required script to the ContactPage_Controller's init() method, while waiting for the SilverStripe guys to come up with new solutions. So that's where I add the Captcha field, just for now... Mind: it will work fine without this!

Again in BalbusContactPage.php:

function init() {
  ...

  $("#Form_ContactForm").validate({
    // how should the fields be validated
    rules: {
      Name: "required",
      Email: {
        required: true,
        email: true
      },
      Captcha: "required"
    },
    // custom message for the Name field
    messages: {
      Name: "$custom_msg_Name"
    }
  });

  ...
}

TODO

  1. check Ajax forms

10 Most recently updated pages

Post your comment

Comments

No one has commented on this page yet.

RSS feed for comments on this page | RSS feed for all comments