diff --git a/CHANGELOG b/CHANGELOG deleted file mode 100644 index 021812b..0000000 --- a/CHANGELOG +++ /dev/null @@ -1,8 +0,0 @@ -0.1: -- initial release - -0.2 -- Renamed 'SpamProtecterManager' to 'SpamProtectorManager'. Note the typo with the 'er' - -0.3 (trunk) -- Updated Error Reporting to be a bit more verbose \ No newline at end of file diff --git a/README.md b/README.md index 2079074..0ac3adc 100644 --- a/README.md +++ b/README.md @@ -14,12 +14,108 @@ SilverStripe 3.0.0 or greater ## Documentation -See docs/ +This module provides a generic, consistent API for adding spam protection to +your SilverStripe Forms. This does not provide any spam protection out of the +box, for that, you must also download one of the spam protection +implementations. Currently available options are: -## Installation Instructions +* [Mollom](https://github.com/silverstripe/silverstripe-mollom) +* [Recaptcha](https://github.com/chillu/silverstripe-recaptcha) +* [MathSpamProtection](https://github.com/silverstripe/silverstripe-mathspamprotection) -See docs/Install +As a developer you can also provide your own protector by creating a class which +implements the `SpamProtector` interface. More on that below. -## Usage Overview +## Configuring -See docs/Install +After installing this module and a protector of your choice (i.e mollom) you'll +need to rebuild your database through `dev/build` and set the default protector +via SilverStripe's config system. This will update any Form instances that have +spam protection hooks with that protector. + +*mysite/_config/spamprotection.yml* + + --- + name: spamprotection + --- + FormSpamProtectionExtension: + default_spam_protector: MollomSpamProtector + +To add spam protection to your form instance call `enableSpamProtection`. + + // your existing form code + $form = new Form( .. ); + $form->enableSpamProtection(); + +The logic to perform the actual spam validation is controlled by each of the +individual `SpamProtector` implementation since they each require a different +implementation client side or server side. + +### Options + +`enableSpamProtection` takes a hash of optional configuration values. + + $form->enableSpamProtection(array( + 'protector' => 'MathSpamProtector', + 'name' => 'Captcha' + )); + +Options to configure are: + +*`protector`* a class name string or class instance which implements +`SpamProtector`. Defaults to your +`FormSpamProtectionExtension.default_spam_protector` value. + +*`name`* the form field name argument for the Captcha. Defaults to `Catcha`. +*`title`* title of the Captcha form field. Defaults to `''` +*`mapping`* an array mapping of the Form fields to the standardized list of +field names. The list of standardized fields to pass to the spam protector are: + + title + body + contextUrl + contextTitle + authorName + authorMail + authorUrl + authorIp + authorId + +## Defining your own `SpamProtector` + +Any class that implements `SpamProtector` and the `getFormField()` method can +be set as the spam protector. The `getFormField()` method returns the +`FormField` to be inserted into the `Form`. The `FormField` returned should be +in charge of the validation process. + + hasExtension('FormSpamProtectionExtension')) { + $form->enableSpamProtection(); + } diff --git a/_config.php b/_config.php index 4f364ab..9104d10 100644 --- a/_config.php +++ b/_config.php @@ -8,12 +8,4 @@ * * @package spamprotection */ - -/** - * If the comments module is installed then add the spam protection module - * to the comments form via this extension. - * - * Place this line in your mysite/_config.php - */ - -// CommentingController::add_extension('CommentSpamProtection'); \ No newline at end of file +Deprecation::notification_version('1.1', 'spamprotection'); \ No newline at end of file diff --git a/_config/spamprotection.yml b/_config/spamprotection.yml new file mode 100644 index 0000000..8c755d1 --- /dev/null +++ b/_config/spamprotection.yml @@ -0,0 +1,6 @@ +--- +name: spamprotection +--- +Form: + extensions: + - FormSpamProtectionExtension \ No newline at end of file diff --git a/code/EditableSpamProtectionField.php b/code/EditableSpamProtectionField.php index 5fec23b..1d591b0 100644 --- a/code/EditableSpamProtectionField.php +++ b/code/EditableSpamProtectionField.php @@ -6,30 +6,29 @@ * * @package spamprotection */ -if(class_exists('EditableFormField')){ +if(class_exists('EditableFormField')) { + class EditableSpamProtectionField extends EditableFormField { static $singular_name = 'Spam Protection Field'; static $plural_name = 'Spam Protection Fields'; - function getFormField() { - if($protector = SpamProtectorManager::get_spam_protector()) { - if($protector) { - $protector = new $protector(); + public function getFormField() { + if($protector = Config::inst()->get('FormSpamProtectionExtension', 'default_spam_protector')) { + $protector = Injector::inst()->create($protector); - return $protector->getFormField($this->Name, $this->Title, null); - } + return $protector->getFormField($this->Name, $this->Title, null); } return false; } - function getFieldValidationOptions() { + public function getFieldValidationOptions() { return new FieldList(); } - function getRequired() { + public function getRequired() { return false; } @@ -37,7 +36,7 @@ if(class_exists('EditableFormField')){ return 'spamprotection/images/' . strtolower($this->class) . '.png'; } - function showInReports() { + public function showInReports() { return false; } } diff --git a/code/SpamProtector.php b/code/SpamProtector.php deleted file mode 100644 index 2312e7f..0000000 --- a/code/SpamProtector.php +++ /dev/null @@ -1,23 +0,0 @@ -spamFieldMapping = $array; - } - - /** - * Get the fields that are mapped via spam protection - * - * @return Array - */ - public function getFieldMapping() { - return $this->spamFieldMapping; - } -} \ No newline at end of file diff --git a/code/SpamProtectorManager.php b/code/SpamProtectorManager.php index 9c77425..1c792d7 100644 --- a/code/SpamProtectorManager.php +++ b/code/SpamProtectorManager.php @@ -1,97 +1,38 @@ getFormField("Captcha", $title, null); - $field->setForm($form); - if ($rightTitle) $field->setRightTitle($rightTitle); - - if($field) { - // update the mapping - $field->setFieldMapping($fieldsToSpamServiceMapping); - - // add the form field - if($before && $form->Fields()->fieldByName($before)) { - $form->Fields()->insertBefore($field, $before); - } - else { - $form->Fields()->push($field); - } - } - - } catch (Exception $e) { - return user_error("SpamProtectorManager::update_form(): '$protectorClass' is not correctly set up. " . $e, E_USER_WARNING); - } - } - - /** - * Send Feedback to the Spam Protection. The level of feedback - * will depend on the Protector class. - * - * @param DataObject The Object which you want to send feedback about. Must have a - * SessionID field. - * @param String Feedback on the $object usually 'spam' or 'ham' for non spam entries - */ - static function send_feedback($object, $feedback) { - $protectorClass = self::get_spam_protector(); - - if(!$protectorClass) return false; - - $protector = new $protectorClass(); - return $protector->sendFeedback($object, $feedback); + public static function update_form($form, $before = null, $fieldsToSpamServiceMapping = array(), $title = null, $rightTitle = null) { + Deprecation::notice('1.1', + 'SpamProtectorManager::update_form is deprecated'. + 'Please use $form->enableSpamProtection() for adding spamprotection' + ); + + return $form->enableSpamProtection(); } } \ No newline at end of file diff --git a/code/extensions/CommentSpamProtection.php b/code/extensions/CommentSpamProtection.php index 9bc32f7..18eabb5 100644 --- a/code/extensions/CommentSpamProtection.php +++ b/code/extensions/CommentSpamProtection.php @@ -1,23 +1,26 @@ 'author_name', - 'URL' => 'author_url', - 'Comment' => 'post_body', - 'Email' => 'author_mail' + $form->enableSpamProtection(array( + 'mapping' => array( + 'Name' => 'authorName', + 'Email' => 'authorEmail', + 'URL' => 'authorUrl', + 'Comment' => 'body', + 'ReturnURL' => 'contextUrl' + ), + 'checks' => array( + 'spam', + 'profanity' + ) )); } } diff --git a/code/extensions/FormSpamProtectionExtension.php b/code/extensions/FormSpamProtectionExtension.php new file mode 100644 index 0000000..ebf7fe9 --- /dev/null +++ b/code/extensions/FormSpamProtectionExtension.php @@ -0,0 +1,117 @@ +create($protector); + } + } else { + $protector = Config::inst()->get('FormSpamProtectionExtension', 'default_spam_protector'); + $protector = Injector::inst()->create($protector); + } + + // captcha form field name (must be unique) + if(isset($options['name'])) { + $name = $options['name']; + } else { + $name = 'Captcha'; + } + + // captcha field title + if(isset($options['title'])) { + $title = $options['title']; + } else { + $title = ''; + } + + // set custom mapping on this form + if(isset($options['mapping'])) { + $this->fieldMapping = $options['mapping']; + } + + // add the form field + if($field = $protector->getFormField($name, $title)) { + $this->owner->Fields()->push($field); + } + + return $this->owner; + } + + /** + * @return bool + */ + public function hasSpamProtectionMapping() { + return ($this->fieldMapping); + } + + /** + * @return array + */ + public function getSpamMappedData() { + if($this->fieldMapping) { + $result = array(); + $data = $this->owner->getData(); + + foreach($this->fieldMapping as $fieldName => $mappedName) { + $result[$mappedName] = (isset($data[$fieldName])) ? $data[$fieldName] : null; + } + + return $result; + } + + return null; + } +} \ No newline at end of file diff --git a/code/interfaces/SpamProtector.php b/code/interfaces/SpamProtector.php new file mode 100644 index 0000000..945e3c3 --- /dev/null +++ b/code/interfaces/SpamProtector.php @@ -0,0 +1,30 @@ + \ No newline at end of file