Merge branch '2'

This commit is contained in:
Robbie Averill 2017-08-28 11:20:58 +12:00
commit 5f8d2af0d1
14 changed files with 205 additions and 112 deletions

View File

@ -24,6 +24,10 @@ if (class_exists('EditableFormField')) {
'EditableNumericField' 'EditableNumericField'
); );
private static $db = array(
'SpamFieldSettings' => 'Text'
);
/** /**
* @var FormField * @var FormField
*/ */
@ -45,7 +49,7 @@ if (class_exists('EditableFormField')) {
$fieldMapping = array(); $fieldMapping = array();
foreach ($this->getCandidateFields() as $otherField) { foreach ($this->getCandidateFields() as $otherField) {
$mapSetting = "Map-{$otherField->Name}"; $mapSetting = "Map-{$otherField->Name}";
$spamField = $this->getSetting($mapSetting); $spamField = $this->spamMapValue($mapSetting);
$fieldMapping[$otherField->Name] = $spamField; $fieldMapping[$otherField->Name] = $spamField;
} }
$protector->setFieldMapping($fieldMapping); $protector->setFieldMapping($fieldMapping);
@ -89,9 +93,47 @@ if (class_exists('EditableFormField')) {
->exclude('Title', ''); // Ignore this field and those without titles ->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() 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 // Get protector
$protector = FormSpamProtectionExtension::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 // Each other text field in this group can be assigned a field mapping
$mapGroup = FieldGroup::create(_t( $mapGroup = FieldGroup::create()
'EditableSpamProtectionField.SPAMFIELDMAPPING', ->setTitle(_t('EditableSpamProtectionField.SPAMFIELDMAPPING', 'Spam Field Mapping'))
'Spam Field Mapping' ->setName('SpamFieldMapping')
))->setDescription(_t( ->setDescription(_t(
'EditableSpamProtectionField.SPAMFIELDMAPPINGDESCRIPTION', 'EditableSpamProtectionField.SPAMFIELDMAPPINGDESCRIPTION',
'Select the form fields that correspond to any relevant spam protection identifiers' 'Select the form fields that correspond to any relevant spam protection identifiers'
)); ));
// Generate field specific settings // Generate field specific settings
$mappableFields = Config::inst()->get('FormSpamProtectionExtension', 'mappable_fields'); $mappableFields = Config::inst()->get('FormSpamProtectionExtension', 'mappable_fields');
@ -118,28 +160,47 @@ if (class_exists('EditableFormField')) {
foreach ($this->getCandidateFields() as $otherField) { foreach ($this->getCandidateFields() as $otherField) {
$mapSetting = "Map-{$otherField->Name}"; $mapSetting = "Map-{$otherField->Name}";
$fieldOption = DropdownField::create( $fieldOption = DropdownField::create(
$this->getSettingName($mapSetting), 'spammap-' . $mapSetting,
$otherField->Title, $otherField->Title,
$mappableFieldsMerged, $mappableFieldsMerged,
$this->getSetting($mapSetting) $this->spamMapValue($mapSetting)
)->setEmptyString(''); )->setEmptyString('');
$mapGroup->push($fieldOption); $mapGroup->push($fieldOption);
} }
$fields->insertBefore($mapGroup, $this->getSettingName('ExtraClass')); $fields->addFieldToTab('Root.Main', $mapGroup);
return $fields; 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 * Using custom validateField method
* as Spam Protection Field implementations may have their own error messages * 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 * and may not be based on the field being required, e.g. Honeypot Field
* *
* @param array $data * @param array $data
* @param Form $form * @param Form $form
* @return void * @return void
*/ */
public function validateField($data, $form) public function validateField($data, $form)
{ {
$formField = $this->getFormField(); $formField = $this->getFormField();
$formField->setForm($form); $formField->setForm($form);

View File

@ -1,6 +1,6 @@
<?php <?php
/** /**
* @package spamprotection * @package spamprotection
* *
* @deprecated 1.0 * @deprecated 1.0
@ -12,7 +12,8 @@ class SpamProtectorManager
public static function set_spam_protector($protector) public static function set_spam_protector($protector)
{ {
Deprecation::notice('1.1', Deprecation::notice(
'1.1',
'SpamProtectorManager::set_spam_protector() is deprecated. '. 'SpamProtectorManager::set_spam_protector() is deprecated. '.
'Use the new config system. FormSpamProtectorExtension.default_spam_protector' 'Use the new config system. FormSpamProtectorExtension.default_spam_protector'
); );
@ -22,16 +23,19 @@ class SpamProtectorManager
public static function get_spam_protector() public static function get_spam_protector()
{ {
Deprecation::notice('1.1', Deprecation::notice(
'1.1',
'SpamProtectorManager::get_spam_protector() is deprecated'. 'SpamProtectorManager::get_spam_protector() is deprecated'.
'Use the new config system. FormSpamProtectorExtension.default_spam_protector'); 'Use the new config system. FormSpamProtectorExtension.default_spam_protector'
);
return self::$spam_protector; return self::$spam_protector;
} }
public static function update_form($form, $before = null, $fieldsToSpamServiceMapping = array(), $title = null, $rightTitle = null) public static function update_form($form, $before = null, $fieldsToSpamServiceMapping = array(), $title = null, $rightTitle = null)
{ {
Deprecation::notice('1.1', Deprecation::notice(
'1.1',
'SpamProtectorManager::update_form is deprecated'. 'SpamProtectorManager::update_form is deprecated'.
'Please use $form->enableSpamProtection() for adding spamprotection' 'Please use $form->enableSpamProtection() for adding spamprotection'
); );

View File

@ -1,4 +1,4 @@
<?php <?php
/** /**
* Apply the spam protection to the comments module if it is installed. * Apply the spam protection to the comments module if it is installed.

View File

@ -1,7 +1,7 @@
<?php <?php
/** /**
* An extension to the {@link Form} class which provides the method * An extension to the {@link Form} class which provides the method
* {@link enableSpamProtection()} helper. * {@link enableSpamProtection()} helper.
* *
* @package spamprotection * @package spamprotection
@ -22,7 +22,7 @@ class FormSpamProtectionExtension extends Extension
/** /**
* @config * @config
* *
* The {@link enableSpamProtection} method will define which of the form * The {@link enableSpamProtection} method will define which of the form
* values correlates to this form mapped fields list. Totally custom forms * values correlates to this form mapped fields list. Totally custom forms
* and subclassed SpamProtector instances are define their own mapping * and subclassed SpamProtector instances are define their own mapping
* *

View File

@ -1,14 +1,14 @@
<?php <?php
/** /**
* SpamProtector base interface. * SpamProtector base interface.
* *
* All Protectors are required implement this interface if they want to appear * All Protectors are required implement this interface if they want to appear
* on the form. * on the form.
* *
* Classes with this interface are used to generate helper lists to allow the * Classes with this interface are used to generate helper lists to allow the
* user to select the protector. * user to select the protector.
* *
* @package spamprotection * @package spamprotection
*/ */
@ -17,9 +17,9 @@ interface SpamProtector
/** /**
* Return the {@link FormField} associated with this protector. * Return the {@link FormField} associated with this protector.
* *
* Most spam methods will simply return a piece of HTML to be injected at * Most spam methods will simply return a piece of HTML to be injected at
* the end of the form. If a spam method needs to inject more than one * the end of the form. If a spam method needs to inject more than one
* form field (i.e a hidden field and a text field) then return a * form field (i.e a hidden field and a text field) then return a
* {@link FieldGroup} from this method to include both. * {@link FieldGroup} from this method to include both.
* *
* @param string $name * @param string $name

View File

@ -18,7 +18,7 @@
}, },
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "2.1.x-dev" "dev-master": "3.0.x-dev"
} }
}, },
"license": "BSD-3-Clause" "license": "BSD-3-Clause"

6
lang/fi.yml Normal file
View File

@ -0,0 +1,6 @@
fi:
EditableSpamProtectionField:
PLURALNAME: 'Roskapostisuojauksen kentät'
SINGULARNAME: 'Roskapostisuojauksen kenttä'
SPAMFIELDMAPPING: 'Roskapostikentän kuvaus'
SPAMFIELDMAPPINGDESCRIPTION: 'Valitse lomakekenttä, joka vastaa mitä tahansa oleellista roskapostisuodatuksen tunnistetta'

6
lang/fi_FI.yml Normal file
View File

@ -0,0 +1,6 @@
fi_FI:
EditableSpamProtectionField:
PLURALNAME: 'Roskapostisuotimen kentät'
SINGULARNAME: 'Roskapostisuotimen kenttä'
SPAMFIELDMAPPING: 'Roskapostikentän kuvaus'
SPAMFIELDMAPPINGDESCRIPTION: 'Valitse lomakekentät, jotka vastaavat mitä tahansa oleellista roskapostisuotimen tunnistetta'

View File

@ -1,26 +1,27 @@
<?php <?php
class EditableSpamProtectionFieldTest extends SapphireTest class EditableSpamProtectionFieldTest extends SapphireTest
{ {
protected $usesDatabase = true; protected $usesDatabase = true;
public function setUp() public function setUp()
{ {
parent::setUp(); parent::setUp();
if (!class_exists('EditableSpamProtectionField')) {
$this->markTestSkipped('"userforms" module not installed');
}
Config::inst()->update( Config::inst()->update(
'FormSpamProtectionExtension', 'default_spam_protector', 'FormSpamProtectionExtension',
'default_spam_protector',
'EditableSpamProtectionFieldTest_Protector' 'EditableSpamProtectionFieldTest_Protector'
); );
} }
public function testValidateFieldDoesntAddErrorOnSuccess() public function testValidateFieldDoesntAddErrorOnSuccess()
{ {
if (!class_exists('EditableSpamProtectionField')) {
$this->markTestSkipped('"userforms" module not installed');
}
$formMock = $this->getFormMock(); $formMock = $this->getFormMock();
$formFieldMock = $this->getEditableFormFieldMock(); $formFieldMock = $this->getEditableFormFieldMock();
@ -39,10 +40,6 @@ class EditableSpamProtectionFieldTest extends SapphireTest
public function testValidateFieldAddsErrorFromField() public function testValidateFieldAddsErrorFromField()
{ {
if (!class_exists('EditableSpamProtectionField')) {
$this->markTestSkipped('"userforms" module not installed');
}
$formMock = $this->getFormMock(); $formMock = $this->getFormMock();
$formFieldMock = $this->getEditableFormFieldMock(); $formFieldMock = $this->getEditableFormFieldMock();
@ -57,17 +54,14 @@ class EditableSpamProtectionFieldTest extends SapphireTest
$formMock $formMock
->expects($this->once()) ->expects($this->once())
->method('addErrorMessage') ->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); $formFieldMock->validateField(array('MyField' => null), $formMock);
} }
public function testValidateFieldAddsDefaultError() public function testValidateFieldAddsDefaultError()
{ {
if (!class_exists('EditableSpamProtectionField')) {
$this->markTestSkipped('"userforms" module not installed');
}
$formMock = $this->getFormMock(); $formMock = $this->getFormMock();
$formFieldMock = $this->getEditableFormFieldMock(); $formFieldMock = $this->getEditableFormFieldMock();
@ -87,6 +81,25 @@ class EditableSpamProtectionFieldTest extends SapphireTest
$formFieldMock->validateField(array('MyField' => null), $formMock); $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() protected function getFormMock()
{ {
$formMock = $this->getMockBuilder('Form', array('addErrorMessage')) $formMock = $this->getMockBuilder('Form', array('addErrorMessage'))
@ -119,17 +132,4 @@ class EditableSpamProtectionFieldTest extends SapphireTest
return $editableFormFieldMock; 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)
{
}
} }

View File

@ -11,7 +11,7 @@ class FormSpamProtectionExtensionTest extends SapphireTest
* @var Form * @var Form
*/ */
protected $form = null; protected $form = null;
public function setUp() public function setUp()
{ {
parent::setUp(); parent::setUp();
@ -20,15 +20,15 @@ class FormSpamProtectionExtensionTest extends SapphireTest
new TextField('Title'), new TextField('Title'),
new TextField('Comment'), new TextField('Comment'),
new TextField('URL') new TextField('URL')
), new FieldList() ), new FieldList());
);
$this->form->disableSecurityToken(); $this->form->disableSecurityToken();
} }
public function testEnableSpamProtection() public function testEnableSpamProtection()
{ {
Config::inst()->update( Config::inst()->update(
'FormSpamProtectionExtension', 'default_spam_protector', 'FormSpamProtectionExtension',
'default_spam_protector',
'FormSpamProtectionExtensionTest_FooProtector' 'FormSpamProtectionExtensionTest_FooProtector'
); );
@ -52,7 +52,7 @@ class FormSpamProtectionExtensionTest extends SapphireTest
'protector' => 'FormSpamProtectionExtensionTest_BarProtector', 'protector' => 'FormSpamProtectionExtensionTest_BarProtector',
'title' => 'Baz', 'title' => 'Baz',
)); ));
$this->assertEquals('Baz', $form->Fields()->fieldByName('Captcha')->Title()); $this->assertEquals('Baz', $form->Fields()->fieldByName('Captcha')->Title());
} }
@ -66,7 +66,7 @@ class FormSpamProtectionExtensionTest extends SapphireTest
$this->assertEquals('Qux', $form->Fields()->fieldByName('Borris')->Title()); $this->assertEquals('Qux', $form->Fields()->fieldByName('Borris')->Title());
} }
public function testConfigurableName() public function testConfigurableName()
{ {
$field_name = "test_configurable_name"; $field_name = "test_configurable_name";
@ -84,28 +84,28 @@ class FormSpamProtectionExtensionTest extends SapphireTest
// field should take up configured name // field should take up configured name
$this->assertEquals('Foo', $form->Fields()->fieldByName($field_name)->Title()); $this->assertEquals('Foo', $form->Fields()->fieldByName($field_name)->Title());
} }
public function testInsertBefore() public function testInsertBefore()
{ {
$form = $this->form->enableSpamProtection(array( $form = $this->form->enableSpamProtection(array(
'protector' => 'FormSpamProtectionExtensionTest_FooProtector', 'protector' => 'FormSpamProtectionExtensionTest_FooProtector',
'insertBefore' => 'URL' 'insertBefore' => 'URL'
)); ));
$fields = $form->Fields(); $fields = $form->Fields();
$this->assertEquals('Title', $fields[0]->Title()); $this->assertEquals('Title', $fields[0]->Title());
$this->assertEquals('Comment', $fields[1]->Title()); $this->assertEquals('Comment', $fields[1]->Title());
$this->assertEquals('Foo', $fields[2]->Title()); $this->assertEquals('Foo', $fields[2]->Title());
$this->assertEquals('URL', $fields[3]->Title()); $this->assertEquals('URL', $fields[3]->Title());
} }
public function testInsertBeforeMissing() public function testInsertBeforeMissing()
{ {
$form = $this->form->enableSpamProtection(array( $form = $this->form->enableSpamProtection(array(
'protector' => 'FormSpamProtectionExtensionTest_FooProtector', 'protector' => 'FormSpamProtectionExtensionTest_FooProtector',
'insertBefore' => 'NotAField' 'insertBefore' => 'NotAField'
)); ));
// field should default to the end instead // field should default to the end instead
$fields = $form->Fields(); $fields = $form->Fields();
$this->assertEquals('Title', $fields[0]->Title()); $this->assertEquals('Title', $fields[0]->Title());
@ -114,49 +114,3 @@ class FormSpamProtectionExtensionTest extends SapphireTest
$this->assertEquals('Foo', $fields[3]->Title()); $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)
{
}
}

View File

@ -0,0 +1,13 @@
<?php
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)
{
}
}

View File

@ -0,0 +1,17 @@
<?php
/**
* @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)
{
}
}

View File

@ -0,0 +1,16 @@
<?php
/**
* @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)
{
}
}

View File

@ -0,0 +1,16 @@
<?php
/**
* @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)
{
}
}