diff --git a/code/EditableSpamProtectionField.php b/code/EditableSpamProtectionField.php index 24a89e7..8993f28 100644 --- a/code/EditableSpamProtectionField.php +++ b/code/EditableSpamProtectionField.php @@ -24,6 +24,10 @@ if (class_exists('EditableFormField')) { 'EditableNumericField' ); + private static $db = array( + 'SpamFieldSettings' => 'Text' + ); + /** * @var FormField */ @@ -45,7 +49,7 @@ if (class_exists('EditableFormField')) { $fieldMapping = array(); foreach ($this->getCandidateFields() as $otherField) { $mapSetting = "Map-{$otherField->Name}"; - $spamField = $this->getSetting($mapSetting); + $spamField = $this->spamMapValue($mapSetting); $fieldMapping[$otherField->Name] = $spamField; } $protector->setFieldMapping($fieldMapping); @@ -89,9 +93,47 @@ if (class_exists('EditableFormField')) { ->exclude('Title', ''); // Ignore this field and those without titles } + /** + * This method is in place for userforms 2.x + * + * @deprecated 3.0 Please use {@link getCMSFields()} instead + */ public function getFieldConfiguration() { - $fields = parent::getFieldConfiguration(); + return $this->getCMSFields(); + } + + /** + * Write the spam field mapping values to a serialised DB field + * + * {@inheritDoc} + */ + public function onBeforeWrite() + { + $fieldMap = Convert::json2array($this->SpamFieldSettings); + if (empty($fieldMap)) { + $fieldMap = array(); + } + + foreach ($this->record as $key => $value) { + if (substr($key, 0, 8) === 'spammap-') { + $fieldMap[substr($key, 8)] = $value; + } + } + $this->setField('SpamFieldSettings', Convert::raw2json($fieldMap)); + + return parent::onBeforeWrite(); + } + + /** + * Used in userforms 3.x and above + * + * {@inheritDoc} + */ + public function getCMSFields() + { + /** @var FieldList $fields */ + $fields = parent::getCMSFields(); // Get protector $protector = FormSpamProtectionExtension::get_protector(); @@ -104,13 +146,13 @@ if (class_exists('EditableFormField')) { } // Each other text field in this group can be assigned a field mapping - $mapGroup = FieldGroup::create(_t( - 'EditableSpamProtectionField.SPAMFIELDMAPPING', - 'Spam Field Mapping' - ))->setDescription(_t( - 'EditableSpamProtectionField.SPAMFIELDMAPPINGDESCRIPTION', - 'Select the form fields that correspond to any relevant spam protection identifiers' - )); + $mapGroup = FieldGroup::create() + ->setTitle(_t('EditableSpamProtectionField.SPAMFIELDMAPPING', 'Spam Field Mapping')) + ->setName('SpamFieldMapping') + ->setDescription(_t( + 'EditableSpamProtectionField.SPAMFIELDMAPPINGDESCRIPTION', + 'Select the form fields that correspond to any relevant spam protection identifiers' + )); // Generate field specific settings $mappableFields = Config::inst()->get('FormSpamProtectionExtension', 'mappable_fields'); @@ -118,28 +160,47 @@ if (class_exists('EditableFormField')) { foreach ($this->getCandidateFields() as $otherField) { $mapSetting = "Map-{$otherField->Name}"; $fieldOption = DropdownField::create( - $this->getSettingName($mapSetting), + 'spammap-' . $mapSetting, $otherField->Title, $mappableFieldsMerged, - $this->getSetting($mapSetting) + $this->spamMapValue($mapSetting) )->setEmptyString(''); $mapGroup->push($fieldOption); } - $fields->insertBefore($mapGroup, $this->getSettingName('ExtraClass')); + $fields->addFieldToTab('Root.Main', $mapGroup); return $fields; } + /** + * Try to retrieve a value for the given spam field map name from the serialised data + * + * @param string $mapSetting + * @return string + */ + public function spamMapValue($mapSetting) + { + $map = Convert::json2array($this->SpamFieldSettings); + if (empty($map)) { + $map = array(); + } + + if (array_key_exists($mapSetting, $map)) { + return $map[$mapSetting]; + } + return ''; + } + /** * Using custom validateField method * as Spam Protection Field implementations may have their own error messages * and may not be based on the field being required, e.g. Honeypot Field - * + * * @param array $data * @param Form $form * @return void */ - public function validateField($data, $form) + public function validateField($data, $form) { $formField = $this->getFormField(); $formField->setForm($form); diff --git a/code/SpamProtectorManager.php b/code/SpamProtectorManager.php index 319f38d..00eb646 100644 --- a/code/SpamProtectorManager.php +++ b/code/SpamProtectorManager.php @@ -1,6 +1,6 @@ enableSpamProtection() for adding spamprotection' ); diff --git a/code/extensions/CommentSpamProtection.php b/code/extensions/CommentSpamProtection.php index e5aca62..453707d 100644 --- a/code/extensions/CommentSpamProtection.php +++ b/code/extensions/CommentSpamProtection.php @@ -1,4 +1,4 @@ -markTestSkipped('"userforms" module not installed'); + } + Config::inst()->update( - 'FormSpamProtectionExtension', 'default_spam_protector', + 'FormSpamProtectionExtension', + 'default_spam_protector', 'EditableSpamProtectionFieldTest_Protector' ); } public function testValidateFieldDoesntAddErrorOnSuccess() { - if (!class_exists('EditableSpamProtectionField')) { - $this->markTestSkipped('"userforms" module not installed'); - } - $formMock = $this->getFormMock(); $formFieldMock = $this->getEditableFormFieldMock(); @@ -39,10 +40,6 @@ class EditableSpamProtectionFieldTest extends SapphireTest public function testValidateFieldAddsErrorFromField() { - if (!class_exists('EditableSpamProtectionField')) { - $this->markTestSkipped('"userforms" module not installed'); - } - $formMock = $this->getFormMock(); $formFieldMock = $this->getEditableFormFieldMock(); @@ -57,17 +54,14 @@ class EditableSpamProtectionFieldTest extends SapphireTest $formMock ->expects($this->once()) ->method('addErrorMessage') - ->with($this->anything(), $this->stringContains('some field message'), $this->anything(), $this->anything());; + ->with($this->anything(), $this->stringContains('some field message'), $this->anything(), $this->anything()); + ; $formFieldMock->validateField(array('MyField' => null), $formMock); } public function testValidateFieldAddsDefaultError() { - if (!class_exists('EditableSpamProtectionField')) { - $this->markTestSkipped('"userforms" module not installed'); - } - $formMock = $this->getFormMock(); $formFieldMock = $this->getEditableFormFieldMock(); @@ -87,6 +81,25 @@ class EditableSpamProtectionFieldTest extends SapphireTest $formFieldMock->validateField(array('MyField' => null), $formMock); } + public function testSpamConfigurationShowsInCms() + { + $field = $this->getEditableFormFieldMock(); + $fields = $field->getCMSFields(); + + $this->assertInstanceOf('FieldGroup', $fields->fieldByName('Root.Main.SpamFieldMapping')); + } + + public function testSpamMapSettingsAreSerialised() + { + $field = $this->getEditableFormFieldMock(); + $field->SpamFieldSettings = json_encode(array('foo' => 'bar', 'bar' => 'baz')); + $field->write(); + + $this->assertJson($field->SpamFieldSettings); + $this->assertSame('bar', $field->spamMapValue('foo')); + $this->assertSame('baz', $field->spamMapValue('bar')); + } + protected function getFormMock() { $formMock = $this->getMockBuilder('Form', array('addErrorMessage')) @@ -119,17 +132,4 @@ class EditableSpamProtectionFieldTest extends SapphireTest return $editableFormFieldMock; } - -} - -class EditableSpamProtectionFieldTest_Protector implements SpamProtector, TestOnly -{ - public function getFormField($name = null, $title = null, $value = null) - { - return new TextField($name, 'Foo', $value); - } - - public function setFieldMapping($fieldMapping) - { - } } diff --git a/tests/FormSpamProtectionExtensionTest.php b/tests/FormSpamProtectionExtensionTest.php index 1df952e..80ff1a9 100644 --- a/tests/FormSpamProtectionExtensionTest.php +++ b/tests/FormSpamProtectionExtensionTest.php @@ -11,7 +11,7 @@ class FormSpamProtectionExtensionTest extends SapphireTest * @var Form */ protected $form = null; - + public function setUp() { parent::setUp(); @@ -20,15 +20,15 @@ class FormSpamProtectionExtensionTest extends SapphireTest new TextField('Title'), new TextField('Comment'), new TextField('URL') - ), new FieldList() - ); + ), new FieldList()); $this->form->disableSecurityToken(); } public function testEnableSpamProtection() { Config::inst()->update( - 'FormSpamProtectionExtension', 'default_spam_protector', + 'FormSpamProtectionExtension', + 'default_spam_protector', 'FormSpamProtectionExtensionTest_FooProtector' ); @@ -52,7 +52,7 @@ class FormSpamProtectionExtensionTest extends SapphireTest 'protector' => 'FormSpamProtectionExtensionTest_BarProtector', 'title' => 'Baz', )); - + $this->assertEquals('Baz', $form->Fields()->fieldByName('Captcha')->Title()); } @@ -66,7 +66,7 @@ class FormSpamProtectionExtensionTest extends SapphireTest $this->assertEquals('Qux', $form->Fields()->fieldByName('Borris')->Title()); } - + public function testConfigurableName() { $field_name = "test_configurable_name"; @@ -84,28 +84,28 @@ class FormSpamProtectionExtensionTest extends SapphireTest // field should take up configured name $this->assertEquals('Foo', $form->Fields()->fieldByName($field_name)->Title()); } - + public function testInsertBefore() { $form = $this->form->enableSpamProtection(array( 'protector' => 'FormSpamProtectionExtensionTest_FooProtector', 'insertBefore' => 'URL' )); - + $fields = $form->Fields(); $this->assertEquals('Title', $fields[0]->Title()); $this->assertEquals('Comment', $fields[1]->Title()); $this->assertEquals('Foo', $fields[2]->Title()); $this->assertEquals('URL', $fields[3]->Title()); } - + public function testInsertBeforeMissing() { $form = $this->form->enableSpamProtection(array( 'protector' => 'FormSpamProtectionExtensionTest_FooProtector', 'insertBefore' => 'NotAField' )); - + // field should default to the end instead $fields = $form->Fields(); $this->assertEquals('Title', $fields[0]->Title()); @@ -114,49 +114,3 @@ class FormSpamProtectionExtensionTest extends SapphireTest $this->assertEquals('Foo', $fields[3]->Title()); } } - -/** - * @package spamprotection - */ -class FormSpamProtectionExtensionTest_BazProtector implements SpamProtector, TestOnly -{ - public function getFormField($name = null, $title = null, $value = null) - { - return new TextField($name, $title, $value); - } - - public function setFieldMapping($fieldMapping) - { - } -} - -/** - * @package spamprotection - */ -class FormSpamProtectionExtensionTest_BarProtector implements SpamProtector, TestOnly -{ - public function getFormField($name = null, $title = null, $value = null) - { - $title = $title ?: 'Bar'; - return new TextField($name, $title, $value); - } - - public function setFieldMapping($fieldMapping) - { - } -} - -/** - * @package spamprotection - */ -class FormSpamProtectionExtensionTest_FooProtector implements SpamProtector, TestOnly -{ - public function getFormField($name = null, $title = null, $value = null) - { - return new TextField($name, 'Foo', $value); - } - - public function setFieldMapping($fieldMapping) - { - } -} diff --git a/tests/Stub/EditableSpamProtectionFieldTest_Protector.php b/tests/Stub/EditableSpamProtectionFieldTest_Protector.php new file mode 100644 index 0000000..eead4e5 --- /dev/null +++ b/tests/Stub/EditableSpamProtectionFieldTest_Protector.php @@ -0,0 +1,13 @@ +