mirror of
https://github.com/silverstripe/silverstripe-spamprotection.git
synced 2024-09-27 20:06:22 +02:00
Compare commits
123 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
26936f33e4 | ||
|
5badc345de | ||
|
eb858ca76e | ||
|
19603c31bc | ||
|
17411fbb95 | ||
|
404ae173d0 | ||
|
afbcf59ec4 | ||
|
5742971245 | ||
|
23843cd97f | ||
|
6ef3acd518 | ||
|
3f62dfd4a4 | ||
|
7c81d075d6 | ||
|
04aefedeef | ||
|
754bcee5da | ||
|
4971ddf3cb | ||
|
9fd768d5ad | ||
|
4e3f68cdb1 | ||
|
c5d644eb71 | ||
|
9a7ed5f091 | ||
|
ed1d210f0d | ||
|
1c99bc8b92 | ||
|
2a55708ae8 | ||
|
2c8fc03f2f | ||
|
688b438e88 | ||
|
fc36247598 | ||
|
0d7a57cedf | ||
|
0e5a2dc66d | ||
|
3b0d8d08ed | ||
|
e028d76a34 | ||
|
4b7d18fe0e | ||
|
8eb3e05f76 | ||
|
63fbae7413 | ||
|
3e9f292082 | ||
|
af01b0ad01 | ||
|
ed7dc6e38e | ||
|
d452367262 | ||
|
a2a21988ed | ||
|
228f2a3058 | ||
|
68d550b817 | ||
|
514b6d7a17 | ||
|
f7febc1e98 | ||
|
04eb8df284 | ||
|
46169f71a0 | ||
|
643fedaf21 | ||
|
9c9900f75a | ||
|
ca6f507af8 | ||
|
c2c4342c01 | ||
|
050ef82451 | ||
|
3a8702b1fa | ||
|
857389c7ff | ||
|
1459ed89ff | ||
|
e717411a9d | ||
|
d5ae93c88e | ||
|
0db3e7aee0 | ||
|
856cc80ffa | ||
|
a20b215e5c | ||
|
a36bb28b0c | ||
|
6ecccd2625 | ||
|
669b189ba7 | ||
|
dce36b8fe7 | ||
|
5978c62022 | ||
|
f3fa9fe9fc | ||
|
e024613ede | ||
|
b88a706ae7 | ||
|
0c445a1dbf | ||
|
6d39bc23ec | ||
|
fc934d93fd | ||
|
506d82fc9d | ||
|
27a40c6210 | ||
|
fe2aed7e58 | ||
|
4c65d66931 | ||
|
b826f232c4 | ||
|
21d8212807 | ||
|
192a1c4c2b | ||
|
0fd7971cd9 | ||
|
f69ee07ec0 | ||
|
059191d91e | ||
|
38ee7a76da | ||
|
46fde9a573 | ||
|
79e2958fad | ||
|
68ba83dd6d | ||
|
4513998f1e | ||
|
1dda806f39 | ||
|
47eef922c7 | ||
|
654f45292c | ||
|
e38c6c3a87 | ||
|
88b1b10f61 | ||
|
0a7b3f768d | ||
|
d09dbdd9f1 | ||
|
b4e9b6e5cb | ||
|
779b155ee0 | ||
|
42c733061d | ||
|
05fcdb6f41 | ||
|
680411e2ac | ||
|
a1ea0df540 | ||
|
cef1e24f86 | ||
|
37dde110c9 | ||
|
c5f0827c2e | ||
|
a60f592598 | ||
|
b757c3dc6d | ||
|
5f8d2af0d1 | ||
|
27da2d6ab4 | ||
|
ef3e6d45b6 | ||
|
d2467ac73a | ||
|
3e7f021de7 | ||
|
5cc9312a8d | ||
|
3d771d8179 | ||
|
4cd01b2c82 | ||
|
a25b052510 | ||
|
2af878f6fa | ||
|
5aa1ca9afb | ||
|
56ec1f42c6 | ||
|
e9880ca3e5 | ||
|
3b4f757d6e | ||
|
b1a8445a75 | ||
|
cc58c0b741 | ||
|
1b3f3b9c62 | ||
|
8e61aeb62b | ||
|
a9545bc842 | ||
|
74b7990058 | ||
|
1c841b25e1 | ||
|
5598dd3517 | ||
|
59c70f297c |
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -4,3 +4,4 @@
|
|||||||
/.gitignore export-ignore
|
/.gitignore export-ignore
|
||||||
/.travis.yml export-ignore
|
/.travis.yml export-ignore
|
||||||
/.scrutinizer.yml export-ignore
|
/.scrutinizer.yml export-ignore
|
||||||
|
/codecov.yml export-ignore
|
||||||
|
11
.github/workflows/ci.yml
vendored
Normal file
11
.github/workflows/ci.yml
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
name: CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
pull_request:
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
ci:
|
||||||
|
name: CI
|
||||||
|
uses: silverstripe/gha-ci/.github/workflows/ci.yml@v1
|
16
.github/workflows/dispatch-ci.yml
vendored
Normal file
16
.github/workflows/dispatch-ci.yml
vendored
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
name: Dispatch CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
# At 11:10 AM UTC, only on Saturday and Sunday
|
||||||
|
schedule:
|
||||||
|
- cron: '10 11 * * 6,0'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
dispatch-ci:
|
||||||
|
name: Dispatch CI
|
||||||
|
# Only run cron on the silverstripe account
|
||||||
|
if: (github.event_name == 'schedule' && github.repository_owner == 'silverstripe') || (github.event_name != 'schedule')
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Dispatch CI
|
||||||
|
uses: silverstripe/gha-dispatch-ci@v1
|
17
.github/workflows/keepalive.yml
vendored
Normal file
17
.github/workflows/keepalive.yml
vendored
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
name: Keepalive
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
# The 4th of every month at 10:50am UTC
|
||||||
|
schedule:
|
||||||
|
- cron: '50 10 4 * *'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
keepalive:
|
||||||
|
name: Keepalive
|
||||||
|
# Only run cron on the silverstripe account
|
||||||
|
if: (github.event_name == 'schedule' && github.repository_owner == 'silverstripe') || (github.event_name != 'schedule')
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Keepalive
|
||||||
|
uses: silverstripe/gha-keepalive@v1
|
@ -1,9 +0,0 @@
|
|||||||
inherit: true
|
|
||||||
|
|
||||||
checks:
|
|
||||||
php:
|
|
||||||
code_rating: true
|
|
||||||
duplication: true
|
|
||||||
|
|
||||||
filter:
|
|
||||||
paths: [code/*, tests/*]
|
|
37
.travis.yml
37
.travis.yml
@ -1,37 +0,0 @@
|
|||||||
# See https://github.com/silverstripe-labs/silverstripe-travis-support for setup details
|
|
||||||
|
|
||||||
sudo: false
|
|
||||||
|
|
||||||
language: php
|
|
||||||
|
|
||||||
php:
|
|
||||||
- 5.3
|
|
||||||
- 5.4
|
|
||||||
- 5.5
|
|
||||||
- 5.6
|
|
||||||
- 7.0
|
|
||||||
|
|
||||||
env:
|
|
||||||
- DB=MYSQL CORE_RELEASE=3.2
|
|
||||||
|
|
||||||
matrix:
|
|
||||||
include:
|
|
||||||
- php: 5.6
|
|
||||||
env: DB=MYSQL CORE_RELEASE=3
|
|
||||||
- php: 5.6
|
|
||||||
env: DB=MYSQL CORE_RELEASE=3.1
|
|
||||||
- php: 5.6
|
|
||||||
env: DB=PGSQL CORE_RELEASE=3.2
|
|
||||||
allow_failures:
|
|
||||||
- php: 7.0
|
|
||||||
|
|
||||||
before_script:
|
|
||||||
- composer self-update || true
|
|
||||||
- git clone git://github.com/silverstripe-labs/silverstripe-travis-support.git ~/travis-support
|
|
||||||
- php ~/travis-support/travis_setup.php --source `pwd` --target ~/builds/ss
|
|
||||||
- cd ~/builds/ss
|
|
||||||
- composer install
|
|
||||||
- composer require silverstripe/userforms
|
|
||||||
|
|
||||||
script:
|
|
||||||
- vendor/bin/phpunit spamprotection/tests
|
|
@ -1,8 +1,9 @@
|
|||||||
[main]
|
[main]
|
||||||
host = https://www.transifex.com
|
host = https://www.transifex.com
|
||||||
|
|
||||||
[silverstripe-spamprotection.master]
|
[o:silverstripe:p:silverstripe-spamprotection:r:master]
|
||||||
file_filter = lang/<lang>.yml
|
file_filter = lang/<lang>.yml
|
||||||
source_file = lang/en.yml
|
source_file = lang/en.yml
|
||||||
source_lang = en
|
source_lang = en
|
||||||
type = YML
|
type = YML
|
||||||
|
|
||||||
|
11
.upgrade.yml
Normal file
11
.upgrade.yml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
mappings:
|
||||||
|
SpamProtector: SilverStripe\SpamProtection\SpamProtector
|
||||||
|
CommentSpamProtection: SilverStripe\SpamProtection\Extension\CommentSpamProtection
|
||||||
|
EditableSpamProtectionField: SilverStripe\SpamProtection\EditableSpamProtectionField
|
||||||
|
FormSpamProtectionExtension: SilverStripe\SpamProtection\Extension\FormSpamProtectionExtension
|
||||||
|
EditableSpamProtectionFieldTest: SilverStripe\SpamProtection\Tests\EditableSpamProtectionFieldTest
|
||||||
|
EditableSpamProtectionFieldTest_Protector: SilverStripe\SpamProtection\Tests\Stub\Protector
|
||||||
|
FormSpamProtectionExtensionTest: SilverStripe\SpamProtection\Tests\FormSpamProtectionExtensionTest
|
||||||
|
FormSpamProtectionExtensionTest_BarProtector: SilverStripe\SpamProtection\Tests\Stub\BarProtector
|
||||||
|
FormSpamProtectionExtensionTest_BazProtector: SilverStripe\SpamProtection\Tests\Stub\BazProtector
|
||||||
|
FormSpamProtectionExtensionTest_FooProtector: SilverStripe\SpamProtection\Tests\Stub\FooProtector
|
135
README.md
135
README.md
@ -1,8 +1,7 @@
|
|||||||
# SpamProtection Module
|
# SpamProtection Module
|
||||||
|
|
||||||
[![Build Status](https://secure.travis-ci.org/silverstripe/silverstripe-spamprotection.png?branch=master)](http://travis-ci.org/silverstripe/silverstripe-spamprotection)
|
[![CI](https://github.com/silverstripe/silverstripe-spamprotection/actions/workflows/ci.yml/badge.svg)](https://github.com/silverstripe/silverstripe-spamprotection/actions/workflows/ci.yml)
|
||||||
![helpfulrobot](https://helpfulrobot.io/silverstripe/spamprotection/badge)
|
[![Silverstripe supported module](https://img.shields.io/badge/silverstripe-supported-0071C4.svg)](https://www.silverstripe.org/software/addons/silverstripe-commercially-supported-module-list/)
|
||||||
|
|
||||||
|
|
||||||
## Maintainer Contact
|
## Maintainer Contact
|
||||||
|
|
||||||
@ -14,22 +13,28 @@
|
|||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
SilverStripe 3.0.0 or greater
|
Silverstripe 4.0+
|
||||||
|
|
||||||
|
**Note:** For Silverstripe 3.x, please use the [2.x release line](https://github.com/silverstripe/silverstripe-spamprotection/tree/2.0).
|
||||||
|
|
||||||
|
## Install
|
||||||
|
|
||||||
|
To install run `composer require silverstripe/spamprotection`.
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
This module provides a generic, consistent API for adding spam protection to
|
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
|
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
|
box. For that, you must also download one of the spam protection
|
||||||
implementations. Currently available options are:
|
implementations. Currently available options are:
|
||||||
|
|
||||||
* [Mollom](https://github.com/silverstripe/silverstripe-mollom)
|
* reCAPTCHA v2 (two implementations: [one](https://github.com/chillu/silverstripe-recaptcha), [two](https://github.com/UndefinedOffset/silverstripe-nocaptcha))
|
||||||
* [Recaptcha](https://github.com/chillu/silverstripe-recaptcha)
|
|
||||||
* [MathSpamProtection](https://github.com/silverstripe/silverstripe-mathspamprotection)
|
* [MathSpamProtection](https://github.com/silverstripe/silverstripe-mathspamprotection)
|
||||||
* [Akismet](https://github.com/tractorcow/silverstripe-akismet)
|
* [Akismet](https://github.com/silverstripe/silverstripe-akismet)
|
||||||
|
* [Mollom](https://github.com/silverstripe-archive/silverstripe-mollom)
|
||||||
|
|
||||||
As a developer you can also provide your own protector by creating a class which
|
As a developer you can also provide your own protector by creating a class which
|
||||||
implements the `SpamProtector` interface. More on that below.
|
implements the `\SilverStripe\SpamProtection\SpamProtector` interface. More on that below.
|
||||||
|
|
||||||
## Configuring
|
## Configuring
|
||||||
|
|
||||||
@ -40,76 +45,89 @@ spam protection hooks with that protector.
|
|||||||
|
|
||||||
*mysite/_config/spamprotection.yml*
|
*mysite/_config/spamprotection.yml*
|
||||||
|
|
||||||
---
|
```yaml
|
||||||
name: spamprotection
|
---
|
||||||
---
|
name: mycustomspamprotection
|
||||||
FormSpamProtectionExtension:
|
---
|
||||||
default_spam_protector: MollomSpamProtector
|
SilverStripe\SpamProtection\Extension\FormSpamProtectionExtension:
|
||||||
|
default_spam_protector: MollomSpamProtector
|
||||||
|
```
|
||||||
|
|
||||||
To add spam protection to your form instance call `enableSpamProtection`.
|
To add spam protection to your form instance call `enableSpamProtection`.
|
||||||
|
|
||||||
// your existing form code
|
```php
|
||||||
$form = new Form( .. );
|
// your existing form code
|
||||||
$form->enableSpamProtection();
|
$form = new Form(/* .. */);
|
||||||
|
$form->enableSpamProtection();
|
||||||
|
```
|
||||||
|
|
||||||
The logic to perform the actual spam validation is controlled by each of the
|
The logic to perform the actual spam validation is controlled by each of the
|
||||||
individual `SpamProtector` implementation since they each require a different
|
individual `SpamProtector` implementations since they each require a different
|
||||||
implementation client side or server side.
|
implementation client side or server side.
|
||||||
|
|
||||||
### Options
|
### Options
|
||||||
|
|
||||||
`enableSpamProtection` takes a hash of optional configuration values.
|
`enableSpamProtection` takes a hash of optional configuration values.
|
||||||
|
|
||||||
$form->enableSpamProtection(array(
|
```php
|
||||||
'protector' => 'MathSpamProtector',
|
$form->enableSpamProtection(array(
|
||||||
'name' => 'Captcha'
|
'protector' => MathSpamProtector::class,
|
||||||
));
|
'name' => 'Captcha'
|
||||||
|
));
|
||||||
|
```
|
||||||
|
|
||||||
Options to configure are:
|
Options to configure are:
|
||||||
|
|
||||||
*`protector`* a class name string or class instance which implements
|
* `protector`: a class name string or class instance which implements
|
||||||
`SpamProtector`. Defaults to your
|
`\SilverStripe\SpamProtection\SpamProtector`. Defaults to your
|
||||||
`FormSpamProtectionExtension.default_spam_protector` value.
|
`SilverStripe\SpamProtection\Extension\FormSpamProtectionExtension.default_spam_protector` value.
|
||||||
|
|
||||||
*`name`* the form field name argument for the Captcha. Defaults to `Catcha`.
|
* `name`: the form field name argument for the Captcha. Defaults to `Captcha`.
|
||||||
*`title`* title of the Captcha form field. Defaults to `''`
|
* `title`: title of the Captcha form field. Defaults to `''`
|
||||||
*`insertBefore`* name of existing field to insert the spam protection field prior to
|
* `insertBefore`: name of existing field to insert the spam protection field prior to
|
||||||
*`mapping`* an array mapping of the Form fields to the standardized list of
|
* `mapping`: an array mapping of the Form fields to the standardised list of
|
||||||
field names. The list of standardized fields to pass to the spam protector are:
|
field names. The list of standardised fields to pass to the spam protector are:
|
||||||
|
|
||||||
title
|
```
|
||||||
body
|
title
|
||||||
contextUrl
|
body
|
||||||
contextTitle
|
contextUrl
|
||||||
authorName
|
contextTitle
|
||||||
authorMail
|
authorName
|
||||||
authorUrl
|
authorMail
|
||||||
authorIp
|
authorUrl
|
||||||
authorId
|
authorIp
|
||||||
|
authorId
|
||||||
|
```
|
||||||
|
|
||||||
## Defining your own `SpamProtector`
|
## Defining your own `SpamProtector`
|
||||||
|
|
||||||
Any class that implements `SpamProtector` and the `getFormField()` method can
|
Any class that implements `\SilverStripe\SpamProtection\SpamProtector` and the `getFormField()` method can
|
||||||
be set as the spam protector. The `getFormField()` method returns the
|
be set as the spam protector. The `getFormField()` method returns the
|
||||||
`FormField` to be inserted into the `Form`. The `FormField` returned should be
|
`FormField` to be inserted into the `Form`. The `FormField` returned should be
|
||||||
in charge of the validation process.
|
in charge of the validation process.
|
||||||
|
|
||||||
<?php
|
```php
|
||||||
|
<?php
|
||||||
|
|
||||||
class CustomSpamProtector implements SpamProtector {
|
use CaptchaField;
|
||||||
|
use SilverStripe\SpamProtection\SpamProtector;
|
||||||
|
|
||||||
public function getFormField($name = null, $title = null, $value = null) {
|
class CustomSpamProtector implements SpamProtector
|
||||||
// CaptchaField is a imagined class which has some functionality.
|
{
|
||||||
// See silverstripe-mollom module for an example.
|
public function getFormField($name = null, $title = null, $value = null)
|
||||||
return new CaptchaField($name, $title, $value);
|
{
|
||||||
}
|
// CaptchaField is an imagined class which has some functionality.
|
||||||
|
// See silverstripe-mollom module for an example.
|
||||||
|
return new CaptchaField($name, $title, $value);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## Using Spam Protection with User Forms
|
## Using Spam Protection with User Forms
|
||||||
|
|
||||||
This module provides an EditableSpamProtectionField wrapper which you can add
|
This module provides an `EditableSpamProtectionField` wrapper which you can add
|
||||||
to your UserForm instances. After installing this module and running /dev/build
|
to your UserForm instances. After installing this module and running `/dev/build`
|
||||||
to rebuild the database, your Form Builder interface will have an option for
|
to rebuild the database, your Form Builder interface will have an option for
|
||||||
`Spam Protection Field`. The type of spam protection used will be based on your
|
`Spam Protection Field`. The type of spam protection used will be based on your
|
||||||
currently selected SpamProtector instance.
|
currently selected SpamProtector instance.
|
||||||
@ -118,10 +136,15 @@ currently selected SpamProtector instance.
|
|||||||
|
|
||||||
Spam protection is useful to provide but in some cases we do not want to require
|
Spam protection is useful to provide but in some cases we do not want to require
|
||||||
the developer to use spam protection. In that case, modules can provide the
|
the developer to use spam protection. In that case, modules can provide the
|
||||||
following pattern
|
following pattern:
|
||||||
|
|
||||||
$form = new Form(..);
|
```php
|
||||||
|
use SilverStripe\Forms\Form;
|
||||||
|
use SilverStripe\SpamProtection\Extension\FormSpamProtectionExtension;
|
||||||
|
|
||||||
if($form->hasExtension('FormSpamProtectionExtension')) {
|
$form = new Form(/* .. */);
|
||||||
$form->enableSpamProtection();
|
|
||||||
}
|
if ($form->hasExtension(FormSpamProtectionExtension::class)) {
|
||||||
|
$form->enableSpamProtection();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
11
_config.php
11
_config.php
@ -1,11 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Default configuration settings for the Spam Protection module.
|
|
||||||
*
|
|
||||||
* You should not put your own configuration in here rather use your
|
|
||||||
* mysite/_config.php file
|
|
||||||
*
|
|
||||||
* @package spamprotection
|
|
||||||
*/
|
|
||||||
Deprecation::notification_version('1.1', 'spamprotection');
|
|
@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: spamprotection
|
Name: spamprotection
|
||||||
---
|
---
|
||||||
Form:
|
SilverStripe\Forms\Form:
|
||||||
extensions:
|
extensions:
|
||||||
- FormSpamProtectionExtension
|
- SilverStripe\SpamProtection\Extension\FormSpamProtectionExtension
|
||||||
|
@ -1,197 +1,284 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
namespace SilverStripe\SpamProtection;
|
||||||
|
|
||||||
|
use SilverStripe\Core\ClassInfo;
|
||||||
|
use SilverStripe\Core\Convert;
|
||||||
|
use SilverStripe\Core\Manifest\ModuleLoader;
|
||||||
|
use SilverStripe\Forms\DropdownField;
|
||||||
|
use SilverStripe\Forms\FieldGroup;
|
||||||
|
use SilverStripe\Forms\FieldList;
|
||||||
|
use SilverStripe\Forms\FormField;
|
||||||
|
use SilverStripe\ORM\DataList;
|
||||||
|
use SilverStripe\ORM\UnsavedRelationList;
|
||||||
|
use SilverStripe\SpamProtection\Extension\FormSpamProtectionExtension;
|
||||||
|
use SilverStripe\UserForms\Model\EditableFormField;
|
||||||
|
use SilverStripe\UserForms\Model\EditableFormField\EditableEmailField;
|
||||||
|
use SilverStripe\UserForms\Model\EditableFormField\EditableNumericField;
|
||||||
|
use SilverStripe\UserForms\Model\EditableFormField\EditableTextField;
|
||||||
|
|
||||||
|
if (!class_exists(EditableFormField::class)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Editable Spam Protecter Field. Used with the User Defined Forms module (if
|
* Editable Spam Protecter Field. Used with the User Defined Forms module (if
|
||||||
* installed) to allow the user to have captcha fields with their custom forms
|
* installed) to allow the user to have captcha fields with their custom forms
|
||||||
*
|
*
|
||||||
* @package spamprotection
|
* @package spamprotection
|
||||||
*/
|
*/
|
||||||
if (class_exists('EditableFormField')) {
|
class EditableSpamProtectionField extends EditableFormField
|
||||||
class EditableSpamProtectionField extends EditableFormField
|
{
|
||||||
|
private static $singular_name = 'Spam Protection Field';
|
||||||
|
|
||||||
|
private static $plural_name = 'Spam Protection Fields';
|
||||||
|
|
||||||
|
private static $table_name = 'EditableSpamProtectionField';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fields to include spam detection for
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
* @config
|
||||||
|
*/
|
||||||
|
private static $check_fields = array(
|
||||||
|
EditableEmailField::class,
|
||||||
|
EditableTextField::class,
|
||||||
|
EditableNumericField::class
|
||||||
|
);
|
||||||
|
|
||||||
|
private static $db = array(
|
||||||
|
'SpamFieldSettings' => 'Text'
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var FormField
|
||||||
|
*/
|
||||||
|
protected $formField = null;
|
||||||
|
|
||||||
|
public function getFormField()
|
||||||
{
|
{
|
||||||
private static $singular_name = 'Spam Protection Field';
|
if ($this->formField) {
|
||||||
|
return $this->formField;
|
||||||
private static $plural_name = 'Spam Protection Fields';
|
|
||||||
/**
|
|
||||||
* Fields to include spam detection for
|
|
||||||
*
|
|
||||||
* @var array
|
|
||||||
* @config
|
|
||||||
*/
|
|
||||||
private static $check_fields = array(
|
|
||||||
'EditableEmailField',
|
|
||||||
'EditableTextField',
|
|
||||||
'EditableNumericField'
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var FormField
|
|
||||||
*/
|
|
||||||
protected $formField = null;
|
|
||||||
|
|
||||||
public function getFormField()
|
|
||||||
{
|
|
||||||
if ($this->formField) {
|
|
||||||
return $this->formField;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get protector
|
|
||||||
$protector = FormSpamProtectionExtension::get_protector();
|
|
||||||
if (!$protector) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extract saved field mappings and update this field.
|
|
||||||
$fieldMapping = array();
|
|
||||||
foreach ($this->getCandidateFields() as $otherField) {
|
|
||||||
$mapSetting = "Map-{$otherField->Name}";
|
|
||||||
$spamField = $this->getSetting($mapSetting);
|
|
||||||
$fieldMapping[$otherField->Name] = $spamField;
|
|
||||||
}
|
|
||||||
$protector->setFieldMapping($fieldMapping);
|
|
||||||
|
|
||||||
// Generate field
|
|
||||||
return $protector->getFormField($this->Name, $this->Title, null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// Get protector
|
||||||
* @param FormField $field
|
$protector = FormSpamProtectionExtension::get_protector();
|
||||||
* @return self
|
if (!$protector) {
|
||||||
*/
|
return false;
|
||||||
public function setFormField(FormField $field)
|
|
||||||
{
|
|
||||||
$this->formField = $field;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// Extract saved field mappings and update this field.
|
||||||
* Gets the list of all candidate spam detectable fields on this field's form
|
$fieldMapping = array();
|
||||||
*
|
foreach ($this->getCandidateFields() as $otherField) {
|
||||||
* @return DataList
|
$mapSetting = "Map-{$otherField->Name}";
|
||||||
*/
|
$spamField = $this->spamMapValue($mapSetting);
|
||||||
protected function getCandidateFields()
|
$fieldMapping[$otherField->Name] = $spamField;
|
||||||
{
|
}
|
||||||
|
$protector->setFieldMapping($fieldMapping);
|
||||||
|
|
||||||
// Get list of all configured classes available for spam detection
|
// Generate field
|
||||||
$types = self::config()->check_fields;
|
$field = $protector->getFormField($this->Name, $this->Title, null);
|
||||||
$typesInherit = array();
|
|
||||||
foreach ($types as $type) {
|
|
||||||
$subTypes = ClassInfo::subclassesFor($type);
|
|
||||||
$typesInherit = array_merge($typesInherit, $subTypes);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get all candidates of the above types
|
$this->doUpdateFormField($field);
|
||||||
return $this
|
|
||||||
->Parent()
|
return $field;
|
||||||
->Fields()
|
}
|
||||||
->filter('ClassName', $typesInherit)
|
|
||||||
->exclude('Title', ''); // Ignore this field and those without titles
|
/**
|
||||||
|
* @param FormField $field
|
||||||
|
* @return self
|
||||||
|
*/
|
||||||
|
public function setFormField(FormField $field)
|
||||||
|
{
|
||||||
|
$this->formField = $field;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the list of all candidate spam detectable fields on this field's form
|
||||||
|
*
|
||||||
|
* @return DataList
|
||||||
|
*/
|
||||||
|
protected function getCandidateFields()
|
||||||
|
{
|
||||||
|
|
||||||
|
// Get list of all configured classes available for spam detection
|
||||||
|
$types = $this->config()->get('check_fields');
|
||||||
|
$typesInherit = array();
|
||||||
|
foreach ($types as $type) {
|
||||||
|
$subTypes = ClassInfo::subclassesFor($type);
|
||||||
|
$typesInherit = array_merge($typesInherit, $subTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getFieldConfiguration()
|
// Get all candidates of the above types
|
||||||
{
|
$parent = $this->Parent();
|
||||||
$fields = parent::getFieldConfiguration();
|
if (!$parent) {
|
||||||
|
return DataList::create(EditableFormField::class);
|
||||||
|
}
|
||||||
|
return $parent
|
||||||
|
->Fields()
|
||||||
|
->filter('ClassName', $typesInherit)
|
||||||
|
->exclude('Title', ''); // Ignore this field and those without titles
|
||||||
|
}
|
||||||
|
|
||||||
// Get protector
|
/**
|
||||||
$protector = FormSpamProtectionExtension::get_protector();
|
* Write the spam field mapping values to a serialised DB field
|
||||||
if (!$protector) {
|
*
|
||||||
return $fields;
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function onBeforeWrite()
|
||||||
|
{
|
||||||
|
$fieldMap = json_decode($this->SpamFieldSettings ?? '', true);
|
||||||
|
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', json_encode($fieldMap));
|
||||||
|
|
||||||
if ($this->Parent()->Fields() instanceof UnsavedRelationList) {
|
return parent::onBeforeWrite();
|
||||||
return $fields;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Each other text field in this group can be assigned a field mapping
|
/**
|
||||||
$mapGroup = FieldGroup::create(_t(
|
* Used in userforms 3.x and above
|
||||||
'EditableSpamProtectionField.SPAMFIELDMAPPING',
|
*
|
||||||
'Spam Field Mapping'
|
* {@inheritDoc}
|
||||||
))->setDescription(_t(
|
*/
|
||||||
'EditableSpamProtectionField.SPAMFIELDMAPPINGDESCRIPTION',
|
public function getCMSFields()
|
||||||
'Select the form fields that correspond to any relevant spam protection identifiers'
|
{
|
||||||
));
|
/** @var FieldList $fields */
|
||||||
|
$fields = parent::getCMSFields();
|
||||||
// Generate field specific settings
|
|
||||||
$mappableFields = Config::inst()->get('FormSpamProtectionExtension', 'mappable_fields');
|
|
||||||
$mappableFieldsMerged = array_combine($mappableFields, $mappableFields);
|
|
||||||
foreach ($this->getCandidateFields() as $otherField) {
|
|
||||||
$mapSetting = "Map-{$otherField->Name}";
|
|
||||||
$fieldOption = DropdownField::create(
|
|
||||||
$this->getSettingName($mapSetting),
|
|
||||||
$otherField->Title,
|
|
||||||
$mappableFieldsMerged,
|
|
||||||
$this->getSetting($mapSetting)
|
|
||||||
)->setEmptyString('');
|
|
||||||
$mapGroup->push($fieldOption);
|
|
||||||
}
|
|
||||||
$fields->insertBefore($mapGroup, $this->getSettingName('ExtraClass'));
|
|
||||||
|
|
||||||
|
// Get protector
|
||||||
|
$protector = FormSpamProtectionExtension::get_protector();
|
||||||
|
if (!$protector) {
|
||||||
return $fields;
|
return $fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
if ($this->Parent()->Fields() instanceof UnsavedRelationList) {
|
||||||
* Using custom validateField method
|
return $fields;
|
||||||
* 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)
|
|
||||||
{
|
|
||||||
$formField = $this->getFormField();
|
|
||||||
$formField->setForm($form);
|
|
||||||
|
|
||||||
if (isset($data[$this->Name])) {
|
// Each other text field in this group can be assigned a field mapping
|
||||||
$formField->setValue($data[$this->Name]);
|
$mapGroup = FieldGroup::create()
|
||||||
}
|
->setTitle(_t(__CLASS__.'.SPAMFIELDMAPPING', 'Spam Field Mapping'))
|
||||||
|
->setName('SpamFieldMapping')
|
||||||
|
->setDescription(_t(
|
||||||
|
__CLASS__.'.SPAMFIELDMAPPINGDESCRIPTION',
|
||||||
|
'Select the form fields that correspond to any relevant spam protection identifiers'
|
||||||
|
));
|
||||||
|
|
||||||
$validator = $form->getValidator();
|
// Generate field specific settings
|
||||||
if (!$formField->validate($validator)) {
|
$mappableFields = FormSpamProtectionExtension::config()->get('mappable_fields');
|
||||||
$errors = $validator->getErrors();
|
$mappableFieldsMerged = array_combine($mappableFields ?? [], $mappableFields ?? []);
|
||||||
$foundError = false;
|
foreach ($this->getCandidateFields() as $otherField) {
|
||||||
|
$mapSetting = "Map-{$otherField->Name}";
|
||||||
|
$fieldOption = DropdownField::create(
|
||||||
|
'spammap-' . $mapSetting,
|
||||||
|
$otherField->Title,
|
||||||
|
$mappableFieldsMerged,
|
||||||
|
$this->spamMapValue($mapSetting)
|
||||||
|
)->setEmptyString('');
|
||||||
|
$mapGroup->push($fieldOption);
|
||||||
|
}
|
||||||
|
$fields->addFieldToTab('Root.Main', $mapGroup);
|
||||||
|
|
||||||
// field validate implementation may not add error to validator
|
return $fields;
|
||||||
if (count($errors) > 0) {
|
}
|
||||||
// check if error already added from fields' validate method
|
|
||||||
foreach ($errors as $error) {
|
/**
|
||||||
if ($error['fieldName'] == $this->Name) {
|
* Try to retrieve a value for the given spam field map name from the serialised data
|
||||||
$foundError = $error;
|
*
|
||||||
break;
|
* @param string $mapSetting
|
||||||
}
|
* @return string
|
||||||
|
*/
|
||||||
|
public function spamMapValue($mapSetting)
|
||||||
|
{
|
||||||
|
$map = json_decode($this->SpamFieldSettings ?? '', true);
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
$formField = $this->getFormField();
|
||||||
|
$formField->setForm($form);
|
||||||
|
|
||||||
|
if (isset($data[$this->Name])) {
|
||||||
|
$formField->setValue($data[$this->Name]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$validator = $form->getValidator();
|
||||||
|
if (!$formField->validate($validator)) {
|
||||||
|
$errors = $validator->getErrors();
|
||||||
|
$foundError = false;
|
||||||
|
|
||||||
|
// field validate implementation may not add error to validator
|
||||||
|
if (count($errors ?? []) > 0) {
|
||||||
|
// check if error already added from fields' validate method
|
||||||
|
foreach ($errors as $error) {
|
||||||
|
if ($error['fieldName'] == $this->Name) {
|
||||||
|
$foundError = $error;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ($foundError !== false) {
|
if ($foundError !== false) {
|
||||||
// use error messaging already set from validate method
|
// use error messaging already set from validate method
|
||||||
$form->addErrorMessage($this->Name, $foundError['message'], $foundError['messageType'], false);
|
$form->sessionMessage($foundError['message'], $foundError['messageType']);
|
||||||
} else {
|
} else {
|
||||||
// fallback to custom message set in CMS or default message if none set
|
// fallback to custom message set in CMS or default message if none set
|
||||||
$form->addErrorMessage($this->Name, $this->getErrorMessage()->HTML(), 'error', false);
|
$form->sessionError($this->getErrorMessage()->HTML());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function getFieldValidationOptions()
|
public function getFieldValidationOptions()
|
||||||
{
|
{
|
||||||
return new FieldList();
|
return FieldList::create();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRequired()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getIcon()
|
||||||
|
{
|
||||||
|
$resource = ModuleLoader::getModule('silverstripe/spamprotection')
|
||||||
|
->getResource('images/editablespamprotectionfield.png');
|
||||||
|
|
||||||
|
if (!$resource->exists()) {
|
||||||
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getRequired()
|
return $resource->getURL();
|
||||||
{
|
}
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getIcon()
|
public function showInReports()
|
||||||
{
|
{
|
||||||
return 'spamprotection/images/' . strtolower($this->class) . '.png';
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
public function showInReports()
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
namespace SilverStripe\SpamProtection\Extension;
|
||||||
|
|
||||||
|
use SilverStripe\Core\Extension;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apply the spam protection to the comments module if it is installed.
|
* Apply the spam protection to the comments module if it is installed.
|
||||||
*
|
*
|
@ -1,5 +1,12 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
namespace SilverStripe\SpamProtection\Extension;
|
||||||
|
|
||||||
|
use LogicException;
|
||||||
|
use SilverStripe\Core\Config\Configurable;
|
||||||
|
use SilverStripe\Core\Extension;
|
||||||
|
use SilverStripe\Core\Injector\Injector;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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.
|
||||||
@ -9,6 +16,8 @@
|
|||||||
|
|
||||||
class FormSpamProtectionExtension extends Extension
|
class FormSpamProtectionExtension extends Extension
|
||||||
{
|
{
|
||||||
|
use Configurable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @config
|
* @config
|
||||||
*
|
*
|
||||||
@ -41,11 +50,20 @@ class FormSpamProtectionExtension extends Extension
|
|||||||
'authorId'
|
'authorId'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @config
|
||||||
|
*
|
||||||
|
* The field name to use for the {@link SpamProtector} {@link FormField}
|
||||||
|
*
|
||||||
|
* @var string $spam_protector
|
||||||
|
*/
|
||||||
|
private static $field_name = "Captcha";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiate a SpamProtector instance
|
* Instantiate a SpamProtector instance
|
||||||
*
|
*
|
||||||
* @param array $options Configuration options
|
* @param array $options Configuration options
|
||||||
* @return SpamProtector
|
* @return SpamProtector|null
|
||||||
*/
|
*/
|
||||||
public static function get_protector($options = null)
|
public static function get_protector($options = null)
|
||||||
{
|
{
|
||||||
@ -53,10 +71,10 @@ class FormSpamProtectionExtension extends Extension
|
|||||||
if (isset($options['protector'])) {
|
if (isset($options['protector'])) {
|
||||||
$protector = $options['protector'];
|
$protector = $options['protector'];
|
||||||
} else {
|
} else {
|
||||||
$protector = Config::inst()->get('FormSpamProtectionExtension', 'default_spam_protector');
|
$protector = self::config()->get('default_spam_protector');
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($protector && class_exists($protector)) {
|
if ($protector && class_exists($protector ?? '')) {
|
||||||
return Injector::inst()->create($protector);
|
return Injector::inst()->create($protector);
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
@ -67,6 +85,8 @@ class FormSpamProtectionExtension extends Extension
|
|||||||
* Activates the spam protection module.
|
* Activates the spam protection module.
|
||||||
*
|
*
|
||||||
* @param array $options
|
* @param array $options
|
||||||
|
* @throws LogicException when get_protector method returns NULL.
|
||||||
|
* @return Object
|
||||||
*/
|
*/
|
||||||
public function enableSpamProtection($options = array())
|
public function enableSpamProtection($options = array())
|
||||||
{
|
{
|
||||||
@ -75,7 +95,7 @@ class FormSpamProtectionExtension extends Extension
|
|||||||
if (isset($options['name'])) {
|
if (isset($options['name'])) {
|
||||||
$name = $options['name'];
|
$name = $options['name'];
|
||||||
} else {
|
} else {
|
||||||
$name = 'Captcha';
|
$name = $this->config()->get('field_name');
|
||||||
}
|
}
|
||||||
|
|
||||||
// captcha field title
|
// captcha field title
|
||||||
@ -88,7 +108,11 @@ class FormSpamProtectionExtension extends Extension
|
|||||||
// set custom mapping on this form
|
// set custom mapping on this form
|
||||||
$protector = self::get_protector($options);
|
$protector = self::get_protector($options);
|
||||||
|
|
||||||
if (isset($options['mapping'])) {
|
if ($protector === null) {
|
||||||
|
throw new LogicException('No spam protector has been set. Null is not valid value.');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($protector && isset($options['mapping'])) {
|
||||||
$protector->setFieldMapping($options['mapping']);
|
$protector->setFieldMapping($options['mapping']);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,7 +124,7 @@ class FormSpamProtectionExtension extends Extension
|
|||||||
// Add before field specified by insertBefore
|
// Add before field specified by insertBefore
|
||||||
$inserted = false;
|
$inserted = false;
|
||||||
if (!empty($options['insertBefore'])) {
|
if (!empty($options['insertBefore'])) {
|
||||||
$inserted = $this->owner->Fields()->insertBefore($field, $options['insertBefore']);
|
$inserted = $this->owner->Fields()->insertBefore($options['insertBefore'], $field);
|
||||||
}
|
}
|
||||||
if (!$inserted) {
|
if (!$inserted) {
|
||||||
// Add field to end if not added already
|
// Add field to end if not added already
|
@ -1,5 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
namespace SilverStripe\SpamProtection;
|
||||||
|
|
||||||
|
use SilverStripe\Forms\FormField;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SpamProtector base interface.
|
* SpamProtector base interface.
|
||||||
*
|
*
|
@ -1,41 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @package spamprotection
|
|
||||||
*
|
|
||||||
* @deprecated 1.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
class SpamProtectorManager
|
|
||||||
{
|
|
||||||
private static $spam_protector = null;
|
|
||||||
|
|
||||||
public static function set_spam_protector($protector)
|
|
||||||
{
|
|
||||||
Deprecation::notice('1.1',
|
|
||||||
'SpamProtectorManager::set_spam_protector() is deprecated. '.
|
|
||||||
'Use the new config system. FormSpamProtectorExtension.default_spam_protector'
|
|
||||||
);
|
|
||||||
|
|
||||||
self::$spam_protector = $protector;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function get_spam_protector()
|
|
||||||
{
|
|
||||||
Deprecation::notice('1.1',
|
|
||||||
'SpamProtectorManager::get_spam_protector() is deprecated'.
|
|
||||||
'Use the new config system. FormSpamProtectorExtension.default_spam_protector');
|
|
||||||
|
|
||||||
return self::$spam_protector;
|
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
1
codecov.yml
Normal file
1
codecov.yml
Normal file
@ -0,0 +1 @@
|
|||||||
|
comment: false
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "silverstripe/spamprotection",
|
"name": "silverstripe/spamprotection",
|
||||||
"description": "Spam protection module for SilverStripe.",
|
"description": "Spam protection module for SilverStripe.",
|
||||||
"type": "silverstripe-module",
|
"type": "silverstripe-vendormodule",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"silverstripe",
|
"silverstripe",
|
||||||
"spamprotection"
|
"spamprotection"
|
||||||
@ -17,11 +17,27 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"silverstripe/framework": "~3.1"
|
"php": "^7.4 || ^8.0",
|
||||||
|
"silverstripe/framework": "^4.10"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpunit/PHPUnit": "~3.7@stable"
|
"phpunit/phpunit": "^9.5",
|
||||||
|
"silverstripe/versioned": "^1.0",
|
||||||
|
"squizlabs/php_codesniffer": "^3.0",
|
||||||
|
"silverstripe/userforms": "^5"
|
||||||
},
|
},
|
||||||
"extra": [],
|
"extra": {
|
||||||
"license": "BSD-3-Clause"
|
"expose": [
|
||||||
|
"images"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"SilverStripe\\SpamProtection\\": "code/",
|
||||||
|
"SilverStripe\\SpamProtection\\Tests\\": "tests/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"license": "BSD-3-Clause",
|
||||||
|
"minimum-stability": "dev",
|
||||||
|
"prefer-stable": true
|
||||||
}
|
}
|
9
lang/da.yml
Normal file
9
lang/da.yml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
da:
|
||||||
|
SilverStripe\SpamProtection\EditableSpamProtectionField:
|
||||||
|
PLURALNAME: 'Spam beskyttelsefelter'
|
||||||
|
PLURALS:
|
||||||
|
one: 'Et spam beskyttelsefelt'
|
||||||
|
other: '{count} Spambeskyttelsefelter'
|
||||||
|
SINGULARNAME: 'Spam beskyttelsesfelt'
|
||||||
|
SPAMFIELDMAPPING: 'Spam felt mapping'
|
||||||
|
SPAMFIELDMAPPINGDESCRIPTION: 'Vælg de formfelter der matcher relevante spam beskyttelses identifikatorer'
|
@ -1,6 +1,9 @@
|
|||||||
de:
|
de:
|
||||||
EditableSpamProtectionField:
|
SilverStripe\SpamProtection\EditableSpamProtectionField:
|
||||||
PLURALNAME: Spamschutzfelder
|
PLURALNAME: Spamschutzfelder
|
||||||
|
PLURALS:
|
||||||
|
one: 'Ein Spamschutzfeld'
|
||||||
|
other: '{count} Spamschutzfelder'
|
||||||
SINGULARNAME: Spamschutzfeld
|
SINGULARNAME: Spamschutzfeld
|
||||||
SPAMFIELDMAPPING: 'Spamschutzfeld Zuordnung'
|
SPAMFIELDMAPPING: 'Spamschutzfeld Zuordnung'
|
||||||
SPAMFIELDMAPPINGDESCRIPTION: 'Wähle die Formularfelder, die mit Spamschutz verbunden sind'
|
SPAMFIELDMAPPINGDESCRIPTION: 'Wähle die Formularfelder, die mit Spamschutz verbunden sind'
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
en:
|
en:
|
||||||
EditableSpamProtectionField:
|
SilverStripe\SpamProtection\EditableSpamProtectionField:
|
||||||
PLURALNAME: 'Spam Protection Fields'
|
PLURALNAME: 'Spam Protection Fields'
|
||||||
|
PLURALS:
|
||||||
|
one: 'A Spam Protection Field'
|
||||||
|
other: '{count} Spam Protection Fields'
|
||||||
SINGULARNAME: 'Spam Protection Field'
|
SINGULARNAME: 'Spam Protection Field'
|
||||||
SPAMFIELDMAPPING: 'Spam Field Mapping'
|
SPAMFIELDMAPPING: 'Spam Field Mapping'
|
||||||
SPAMFIELDMAPPINGDESCRIPTION: 'Select the form fields that correspond to any relevant spam protection identifiers'
|
SPAMFIELDMAPPINGDESCRIPTION: 'Select the form fields that correspond to any relevant spam protection identifiers'
|
||||||
|
db_SpamFieldSettings: 'Spam field settings'
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
eo:
|
eo:
|
||||||
EditableSpamProtectionField:
|
SilverStripe\SpamProtection\EditableSpamProtectionField:
|
||||||
PLURALNAME: 'Spamprotektaj kampoj'
|
PLURALNAME: 'Spamprotektaj kampoj'
|
||||||
|
PLURALS:
|
||||||
|
one: 'Unu spamprotekta kampo'
|
||||||
|
other: '{count} spamprotektaj kampoj'
|
||||||
SINGULARNAME: 'Spamprotekta kampo'
|
SINGULARNAME: 'Spamprotekta kampo'
|
||||||
SPAMFIELDMAPPING: 'Spamkampa mapigo'
|
SPAMFIELDMAPPING: 'Spamkampa mapigo'
|
||||||
SPAMFIELDMAPPINGDESCRIPTION: 'Elektu la kampojn kiuj rilatas al eventualaj rilataj spamprotektaj identigiloj'
|
SPAMFIELDMAPPINGDESCRIPTION: 'Elektu la kampojn kiuj rilatas al eventualaj rilataj spamprotektaj identigiloj'
|
||||||
|
db_SpamFieldSettings: 'Spamkampaj agordoj'
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
es:
|
es:
|
||||||
EditableSpamProtectionField:
|
SilverStripe\SpamProtection\EditableSpamProtectionField:
|
||||||
PLURALNAME: 'Campos de protección de spam'
|
PLURALNAME: 'Campos de protección de spam'
|
||||||
SINGULARNAME: 'Campo de protección de spam'
|
SINGULARNAME: 'Campo de protección de spam'
|
||||||
SPAMFIELDMAPPING: 'Mapeo del campo spam'
|
SPAMFIELDMAPPING: 'Mapeo del campo spam'
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
fa_IR:
|
fa_IR:
|
||||||
EditableSpamProtectionField:
|
SilverStripe\SpamProtection\EditableSpamProtectionField:
|
||||||
PLURALNAME: 'فیلدهای محافظت از هرزنوشته'
|
PLURALNAME: 'فیلدهای محافظت از هرزنوشته'
|
||||||
SINGULARNAME: 'فیلد محافظت از هرزنوشته'
|
SINGULARNAME: 'فیلد محافظت از هرزنوشته'
|
||||||
SPAMFIELDMAPPING: 'نقشهبرداری فیلد هرزنوشته'
|
SPAMFIELDMAPPING: 'نقشهبرداری فیلد هرزنوشته'
|
||||||
|
9
lang/fi.yml
Normal file
9
lang/fi.yml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
fi:
|
||||||
|
SilverStripe\SpamProtection\EditableSpamProtectionField:
|
||||||
|
PLURALNAME: 'Roskapostisuojauksen kentät'
|
||||||
|
PLURALS:
|
||||||
|
one: 'Roskapostin suodatuskenttä'
|
||||||
|
other: '{count} Roskapostin suodatuskenttää'
|
||||||
|
SINGULARNAME: 'Roskapostisuojauksen kenttä'
|
||||||
|
SPAMFIELDMAPPING: 'Roskapostikentän kuvaus'
|
||||||
|
SPAMFIELDMAPPINGDESCRIPTION: 'Valitse lomakekenttä, joka vastaa mitä tahansa oleellista roskapostisuodatuksen tunnistetta'
|
9
lang/fi_FI.yml
Normal file
9
lang/fi_FI.yml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
fi_FI:
|
||||||
|
SilverStripe\SpamProtection\EditableSpamProtectionField:
|
||||||
|
PLURALNAME: 'Roskapostisuojauksen kentät'
|
||||||
|
PLURALS:
|
||||||
|
one: 'Roskapostin suodatuskenttä'
|
||||||
|
other: '{count} Roskapostin suodatuskenttää'
|
||||||
|
SINGULARNAME: 'Roskapostisuojauksen kenttä'
|
||||||
|
SPAMFIELDMAPPING: 'Roskapostikentän kuvaus'
|
||||||
|
SPAMFIELDMAPPINGDESCRIPTION: 'Valitse lomakekenttä, joka vastaa mitä tahansa oleellista roskapostisuodatuksen tunnistetta'
|
@ -1,5 +1,5 @@
|
|||||||
hr:
|
hr:
|
||||||
EditableSpamProtectionField:
|
SilverStripe\SpamProtection\EditableSpamProtectionField:
|
||||||
PLURALNAME: 'Polja Spam zaštite'
|
PLURALNAME: 'Polja Spam zaštite'
|
||||||
SINGULARNAME: 'Polje Spam zaštite'
|
SINGULARNAME: 'Polje Spam zaštite'
|
||||||
SPAMFIELDMAPPING: 'Mapiranje polja Spama'
|
SPAMFIELDMAPPING: 'Mapiranje polja Spama'
|
||||||
|
10
lang/it.yml
Normal file
10
lang/it.yml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
it:
|
||||||
|
SilverStripe\SpamProtection\EditableSpamProtectionField:
|
||||||
|
PLURALNAME: 'Campi di Prevenzione Spam'
|
||||||
|
PLURALS:
|
||||||
|
many: '{count} Campi di Prevenzione Spam'
|
||||||
|
one: 'Un Campo di Prevenzione Spam'
|
||||||
|
other: '{count} Campi di Prevenzione Spam'
|
||||||
|
SINGULARNAME: 'Campo di Prevenzione Spam'
|
||||||
|
SPAMFIELDMAPPING: 'Mappatura Campo Spam'
|
||||||
|
SPAMFIELDMAPPINGDESCRIPTION: 'Selezionare i campi della form che forniscono una qualche protezione dallo spam'
|
9
lang/nl.yml
Normal file
9
lang/nl.yml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
nl:
|
||||||
|
SilverStripe\SpamProtection\EditableSpamProtectionField:
|
||||||
|
PLURALNAME: 'Anti-spam velden'
|
||||||
|
PLURALS:
|
||||||
|
one: 'Een anti-spam veld'
|
||||||
|
other: '{count} Anti-spam velden'
|
||||||
|
SINGULARNAME: 'Anti-spam veld'
|
||||||
|
SPAMFIELDMAPPING: 'Spam-velden koppelen'
|
||||||
|
SPAMFIELDMAPPINGDESCRIPTION: 'Kies de velden die overeenkomen met de anti-spam identifiers'
|
@ -1,5 +1,5 @@
|
|||||||
ru:
|
ru:
|
||||||
EditableSpamProtectionField:
|
SilverStripe\SpamProtection\EditableSpamProtectionField:
|
||||||
PLURALNAME: 'Поля защиты от спама'
|
PLURALNAME: 'Поля защиты от спама'
|
||||||
SINGULARNAME: 'Поле защиты от спама'
|
SINGULARNAME: 'Поле защиты от спама'
|
||||||
SPAMFIELDMAPPING: 'Привязка полей для защиты от спама'
|
SPAMFIELDMAPPING: 'Привязка полей для защиты от спама'
|
||||||
|
@ -1,6 +1,12 @@
|
|||||||
sk:
|
sk:
|
||||||
EditableSpamProtectionField:
|
SilverStripe\SpamProtection\EditableSpamProtectionField:
|
||||||
PLURALNAME: 'Polia ochrany proti spamu'
|
PLURALNAME: 'Polia ochrany proti spamu'
|
||||||
|
PLURALS:
|
||||||
|
few: '{count} polia ochrany proti spamu'
|
||||||
|
many: '{count} polí ochrany proti spamu'
|
||||||
|
one: 'Pole ochrany proti spamu'
|
||||||
|
other: '{count} polí ochrany proti spamu'
|
||||||
SINGULARNAME: 'Pole ochrany proti spamu'
|
SINGULARNAME: 'Pole ochrany proti spamu'
|
||||||
SPAMFIELDMAPPING: 'Mapovanie spamového poľa'
|
SPAMFIELDMAPPING: 'Mapovanie spamového poľa'
|
||||||
SPAMFIELDMAPPINGDESCRIPTION: 'Vyberte polia formulára, ktoré zodpovedajú všetkým príslušným identifikátorom ochrany proti spamu'
|
SPAMFIELDMAPPINGDESCRIPTION: 'Vyberte polia formulára, ktoré zodpovedajú všetkým príslušným identifikátorom ochrany proti spamu'
|
||||||
|
db_SpamFieldSettings: 'Nastavenia poľa spamu'
|
||||||
|
4
lang/sl.yml
Normal file
4
lang/sl.yml
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
sl:
|
||||||
|
SilverStripe\SpamProtection\EditableSpamProtectionField:
|
||||||
|
PLURALNAME: 'Polja za zaščito pred neželeno pošto'
|
||||||
|
SINGULARNAME: 'Polje za zaščito pred neželeno pošto'
|
6
legacy.yml
Normal file
6
legacy.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
Name: spamprotectionlegacy
|
||||||
|
---
|
||||||
|
SilverStripe\ORM\DatabaseAdmin:
|
||||||
|
classname_value_remapping:
|
||||||
|
EditableSpamProtectionField: 'SilverStripe\SpamProtection\EditableSpamProtectionField'
|
@ -1,4 +1,4 @@
|
|||||||
Copyright (c) 2016, SilverStripe Limited
|
Copyright (c) 2017, SilverStripe Limited
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||||
|
13
phpcs.xml.dist
Normal file
13
phpcs.xml.dist
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ruleset name="SilverStripe">
|
||||||
|
<description>CodeSniffer ruleset for SilverStripe coding conventions.</description>
|
||||||
|
|
||||||
|
<file>code</file>
|
||||||
|
<file>tests</file>
|
||||||
|
|
||||||
|
<rule ref="PSR2" >
|
||||||
|
<!-- Current exclusions -->
|
||||||
|
<exclude name="PSR1.Methods.CamelCapsMethodName" />
|
||||||
|
<exclude name="PSR1.Files.SideEffects.FoundWithSymbols" />
|
||||||
|
</rule>
|
||||||
|
</ruleset>
|
17
phpunit.xml.dist
Normal file
17
phpunit.xml.dist
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<phpunit bootstrap="vendor/silverstripe/framework/tests/bootstrap.php" colors="true">
|
||||||
|
<testsuites>
|
||||||
|
<testsuite name="Default">
|
||||||
|
<directory>tests</directory>
|
||||||
|
</testsuite>
|
||||||
|
</testsuites>
|
||||||
|
|
||||||
|
<filter>
|
||||||
|
<whitelist addUncoveredFilesFromWhitelist="true">
|
||||||
|
<directory suffix=".php">code/</directory>
|
||||||
|
<exclude>
|
||||||
|
<directory suffix=".php">tests/</directory>
|
||||||
|
</exclude>
|
||||||
|
</whitelist>
|
||||||
|
</filter>
|
||||||
|
</phpunit>
|
@ -1,26 +1,41 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
namespace SilverStripe\SpamProtection\Tests;
|
||||||
|
|
||||||
|
use ReflectionClass;
|
||||||
|
use SilverStripe\ORM\DataList;
|
||||||
|
use SilverStripe\UserForms\Model\UserDefinedForm;
|
||||||
|
use SilverStripe\Core\Config\Config;
|
||||||
|
use SilverStripe\Dev\SapphireTest;
|
||||||
|
use SilverStripe\Forms\FieldGroup;
|
||||||
|
use SilverStripe\Forms\Form;
|
||||||
|
use SilverStripe\Forms\RequiredFields;
|
||||||
|
use SilverStripe\Forms\TextField;
|
||||||
|
use SilverStripe\SpamProtection\EditableSpamProtectionField;
|
||||||
|
use SilverStripe\SpamProtection\Extension\FormSpamProtectionExtension;
|
||||||
|
use SilverStripe\SpamProtection\Tests\Stub\Protector;
|
||||||
|
|
||||||
class EditableSpamProtectionFieldTest extends SapphireTest
|
class EditableSpamProtectionFieldTest extends SapphireTest
|
||||||
{
|
{
|
||||||
|
|
||||||
protected $usesDatabase = true;
|
protected $usesDatabase = true;
|
||||||
|
|
||||||
public function setUp()
|
protected function setUp(): void
|
||||||
{
|
{
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
|
|
||||||
Config::inst()->update(
|
if (!class_exists(EditableSpamProtectionField::class)) {
|
||||||
'FormSpamProtectionExtension', 'default_spam_protector',
|
$this->markTestSkipped('"userforms" module not installed');
|
||||||
'EditableSpamProtectionFieldTest_Protector'
|
}
|
||||||
|
|
||||||
|
Config::modify()->set(
|
||||||
|
FormSpamProtectionExtension::class,
|
||||||
|
'default_spam_protector',
|
||||||
|
Protector::class
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
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();
|
||||||
|
|
||||||
@ -32,17 +47,13 @@ class EditableSpamProtectionFieldTest extends SapphireTest
|
|||||||
|
|
||||||
$formMock
|
$formMock
|
||||||
->expects($this->never())
|
->expects($this->never())
|
||||||
->method('addErrorMessage');
|
->method('sessionMessage');
|
||||||
|
|
||||||
$formFieldMock->validateField(array('MyField' => null), $formMock);
|
$formFieldMock->validateField(array('MyField' => null), $formMock);
|
||||||
}
|
}
|
||||||
|
|
||||||
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();
|
||||||
|
|
||||||
@ -56,18 +67,14 @@ class EditableSpamProtectionFieldTest extends SapphireTest
|
|||||||
|
|
||||||
$formMock
|
$formMock
|
||||||
->expects($this->once())
|
->expects($this->once())
|
||||||
->method('addErrorMessage')
|
->method('sessionMessage')
|
||||||
->with($this->anything(), $this->stringContains('some field message'), $this->anything(), $this->anything());;
|
->with($this->stringContains('some field message'), $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();
|
||||||
|
|
||||||
@ -81,17 +88,45 @@ class EditableSpamProtectionFieldTest extends SapphireTest
|
|||||||
|
|
||||||
$formMock
|
$formMock
|
||||||
->expects($this->once())
|
->expects($this->once())
|
||||||
->method('addErrorMessage')
|
->method('sessionError')
|
||||||
->with($this->anything(), $this->stringContains('default error message'), $this->anything(), $this->anything());
|
->with($this->stringContains('default error message'));
|
||||||
|
|
||||||
$formFieldMock->validateField(array('MyField' => null), $formMock);
|
$formFieldMock->validateField(array('MyField' => null), $formMock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testSpamConfigurationShowsInCms()
|
||||||
|
{
|
||||||
|
$field = $this->getEditableFormFieldMock();
|
||||||
|
$fields = $field->getCMSFields();
|
||||||
|
|
||||||
|
$this->assertInstanceOf(FieldGroup::class, $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'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetIcon()
|
||||||
|
{
|
||||||
|
$field = new EditableSpamProtectionField;
|
||||||
|
|
||||||
|
$this->assertStringContainsString('/images/editablespamprotectionfield.png', $field->getIcon());
|
||||||
|
}
|
||||||
|
|
||||||
protected function getFormMock()
|
protected function getFormMock()
|
||||||
{
|
{
|
||||||
$formMock = $this->getMockBuilder('Form', array('addErrorMessage'))
|
$formMock = $this->getMockBuilder(Form::class)
|
||||||
|
->setMethods(['sessionMessage', 'sessionError', 'getValidator'])
|
||||||
->disableOriginalConstructor()
|
->disableOriginalConstructor()
|
||||||
->getMock();
|
->getMock();
|
||||||
|
|
||||||
$formMock
|
$formMock
|
||||||
->expects($this->any())
|
->expects($this->any())
|
||||||
->method('getValidator')
|
->method('getValidator')
|
||||||
@ -105,12 +140,13 @@ class EditableSpamProtectionFieldTest extends SapphireTest
|
|||||||
$page = new UserDefinedForm();
|
$page = new UserDefinedForm();
|
||||||
$page->write();
|
$page->write();
|
||||||
|
|
||||||
$formFieldMock = $this->getMockBuilder('TextField')
|
$formFieldMock = $this->getMockBuilder(TextField::class)
|
||||||
->disableOriginalConstructor()
|
->disableOriginalConstructor()
|
||||||
->getMock();
|
->getMock();
|
||||||
|
|
||||||
$editableFormFieldMock = new EditableSpamProtectionField(array(
|
$editableFormFieldMock = new EditableSpamProtectionField(array(
|
||||||
'ParentID' => $page->ID,
|
'ParentID' => $page->ID,
|
||||||
|
'ParentClass' => get_class($page),
|
||||||
'Name' => 'MyField',
|
'Name' => 'MyField',
|
||||||
'CustomErrorMessage' => 'default error message'
|
'CustomErrorMessage' => 'default error message'
|
||||||
));
|
));
|
||||||
@ -120,16 +156,23 @@ class EditableSpamProtectionFieldTest extends SapphireTest
|
|||||||
return $editableFormFieldMock;
|
return $editableFormFieldMock;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
public function testGetCandidateFieldsParentStatus()
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
|
$field = new EditableSpamProtectionField();
|
||||||
|
$field->Name = 'MyField';
|
||||||
|
$reflection = new ReflectionClass($field);
|
||||||
|
$method = $reflection->getMethod('getCandidateFields');
|
||||||
|
$method->setAccessible(true);
|
||||||
|
// Assert with no parent
|
||||||
|
$list = $method->invoke($field);
|
||||||
|
$this->assertTrue($list instanceof DataList);
|
||||||
|
// Assert with parent
|
||||||
|
$page = new UserDefinedForm();
|
||||||
|
$page->write();
|
||||||
|
$field->ParentID = $page->ID;
|
||||||
|
$field->ParentClass = get_class($page);
|
||||||
|
$field->write();
|
||||||
|
$list = $method->invoke($field);
|
||||||
|
$this->assertTrue($list instanceof DataList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,19 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
namespace SilverStripe\SpamProtection\Tests;
|
||||||
|
|
||||||
|
use LogicException;
|
||||||
|
use SilverStripe\Control\Controller;
|
||||||
|
use SilverStripe\Core\Config\Config;
|
||||||
|
use SilverStripe\Dev\SapphireTest;
|
||||||
|
use SilverStripe\Forms\FieldList;
|
||||||
|
use SilverStripe\Forms\Form;
|
||||||
|
use SilverStripe\Forms\TextField;
|
||||||
|
use SilverStripe\SpamProtection\Extension\FormSpamProtectionExtension;
|
||||||
|
use SilverStripe\SpamProtection\Tests\Stub\FooProtector;
|
||||||
|
use SilverStripe\SpamProtection\Tests\Stub\BarProtector;
|
||||||
|
use SilverStripe\SpamProtection\Tests\Stub\BazProtector;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @package spamprotection
|
* @package spamprotection
|
||||||
*/
|
*/
|
||||||
@ -12,24 +26,34 @@ class FormSpamProtectionExtensionTest extends SapphireTest
|
|||||||
*/
|
*/
|
||||||
protected $form = null;
|
protected $form = null;
|
||||||
|
|
||||||
public function setUp()
|
protected function setUp(): void
|
||||||
{
|
{
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
|
|
||||||
$this->form = new Form($this, 'Form', new FieldList(
|
$this->form = new Form(new Controller, 'Form', new FieldList(
|
||||||
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 testEnableSpamProtectionThrowsException()
|
||||||
|
{
|
||||||
|
$this->expectException(LogicException::class);
|
||||||
|
$this->expectExceptionMessage('No spam protector has been set. Null is not valid value.');
|
||||||
|
|
||||||
|
Config::modify()->set(FormSpamProtectionExtension::class, 'default_spam_protector', null);
|
||||||
|
$this->form->enableSpamProtection();
|
||||||
|
}
|
||||||
|
|
||||||
public function testEnableSpamProtection()
|
public function testEnableSpamProtection()
|
||||||
{
|
{
|
||||||
Config::inst()->update(
|
Config::modify()->set(
|
||||||
'FormSpamProtectionExtension', 'default_spam_protector',
|
FormSpamProtectionExtension::class,
|
||||||
'FormSpamProtectionExtensionTest_FooProtector'
|
'default_spam_protector',
|
||||||
|
FooProtector::class
|
||||||
);
|
);
|
||||||
|
|
||||||
$form = $this->form->enableSpamProtection();
|
$form = $this->form->enableSpamProtection();
|
||||||
@ -40,7 +64,7 @@ class FormSpamProtectionExtensionTest extends SapphireTest
|
|||||||
public function testEnableSpamProtectionCustomProtector()
|
public function testEnableSpamProtectionCustomProtector()
|
||||||
{
|
{
|
||||||
$form = $this->form->enableSpamProtection(array(
|
$form = $this->form->enableSpamProtection(array(
|
||||||
'protector' => 'FormSpamProtectionExtensionTest_BarProtector'
|
'protector' => BarProtector::class
|
||||||
));
|
));
|
||||||
|
|
||||||
$this->assertEquals('Bar', $form->Fields()->fieldByName('Captcha')->Title());
|
$this->assertEquals('Bar', $form->Fields()->fieldByName('Captcha')->Title());
|
||||||
@ -49,7 +73,7 @@ class FormSpamProtectionExtensionTest extends SapphireTest
|
|||||||
public function testEnableSpamProtectionCustomTitle()
|
public function testEnableSpamProtectionCustomTitle()
|
||||||
{
|
{
|
||||||
$form = $this->form->enableSpamProtection(array(
|
$form = $this->form->enableSpamProtection(array(
|
||||||
'protector' => 'FormSpamProtectionExtensionTest_BarProtector',
|
'protector' => BarProtector::class,
|
||||||
'title' => 'Baz',
|
'title' => 'Baz',
|
||||||
));
|
));
|
||||||
|
|
||||||
@ -59,7 +83,7 @@ class FormSpamProtectionExtensionTest extends SapphireTest
|
|||||||
public function testCustomOptions()
|
public function testCustomOptions()
|
||||||
{
|
{
|
||||||
$form = $this->form->enableSpamProtection(array(
|
$form = $this->form->enableSpamProtection(array(
|
||||||
'protector' => 'FormSpamProtectionExtensionTest_BazProtector',
|
'protector' => BazProtector::class,
|
||||||
'title' => 'Qux',
|
'title' => 'Qux',
|
||||||
'name' => 'Borris'
|
'name' => 'Borris'
|
||||||
));
|
));
|
||||||
@ -67,10 +91,30 @@ class FormSpamProtectionExtensionTest extends SapphireTest
|
|||||||
$this->assertEquals('Qux', $form->Fields()->fieldByName('Borris')->Title());
|
$this->assertEquals('Qux', $form->Fields()->fieldByName('Borris')->Title());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testConfigurableName()
|
||||||
|
{
|
||||||
|
$field_name = "test_configurable_name";
|
||||||
|
Config::modify()->set(
|
||||||
|
FormSpamProtectionExtension::class,
|
||||||
|
'default_spam_protector',
|
||||||
|
FooProtector::class
|
||||||
|
);
|
||||||
|
Config::modify()->set(
|
||||||
|
FormSpamProtectionExtension::class,
|
||||||
|
'field_name',
|
||||||
|
$field_name
|
||||||
|
);
|
||||||
|
$form = $this->form->enableSpamProtection();
|
||||||
|
// remove for subsequent tests
|
||||||
|
Config::modify()->remove(FormSpamProtectionExtension::class, 'field_name');
|
||||||
|
// field should take up configured name
|
||||||
|
$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' => FooProtector::class,
|
||||||
'insertBefore' => 'URL'
|
'insertBefore' => 'URL'
|
||||||
));
|
));
|
||||||
|
|
||||||
@ -84,7 +128,7 @@ class FormSpamProtectionExtensionTest extends SapphireTest
|
|||||||
public function testInsertBeforeMissing()
|
public function testInsertBeforeMissing()
|
||||||
{
|
{
|
||||||
$form = $this->form->enableSpamProtection(array(
|
$form = $this->form->enableSpamProtection(array(
|
||||||
'protector' => 'FormSpamProtectionExtensionTest_FooProtector',
|
'protector' => FooProtector::class,
|
||||||
'insertBefore' => 'NotAField'
|
'insertBefore' => 'NotAField'
|
||||||
));
|
));
|
||||||
|
|
||||||
@ -96,49 +140,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)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
23
tests/FormSpamProtectionExtensionTest/BarProtector.php
Normal file
23
tests/FormSpamProtectionExtensionTest/BarProtector.php
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace SilverStripe\SpamProtection\Tests\FormSpamProtectionExtensionTest;
|
||||||
|
|
||||||
|
use SilverStripe\Dev\TestOnly;
|
||||||
|
use SilverStripe\Forms\TextField;
|
||||||
|
use SilverStripe\SpamProtection\SpamProtector;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @package spamprotection
|
||||||
|
*/
|
||||||
|
class 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)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
22
tests/FormSpamProtectionExtensionTest/BazProtector.php
Normal file
22
tests/FormSpamProtectionExtensionTest/BazProtector.php
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace SilverStripe\SpamProtection\Tests\FormSpamProtectionExtensionTest;
|
||||||
|
|
||||||
|
use SilverStripe\Dev\TestOnly;
|
||||||
|
use SilverStripe\Forms\TextField;
|
||||||
|
use SilverStripe\SpamProtection\SpamProtector;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @package spamprotection
|
||||||
|
*/
|
||||||
|
class BazProtector implements SpamProtector, TestOnly
|
||||||
|
{
|
||||||
|
public function getFormField($name = null, $title = null, $value = null)
|
||||||
|
{
|
||||||
|
return new TextField($name, $title, $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setFieldMapping($fieldMapping)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
22
tests/FormSpamProtectionExtensionTest/FooProtector.php
Normal file
22
tests/FormSpamProtectionExtensionTest/FooProtector.php
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace SilverStripe\SpamProtection\Tests\FormSpamProtectionExtensionTest;
|
||||||
|
|
||||||
|
use SilverStripe\Dev\TestOnly;
|
||||||
|
use SilverStripe\Forms\TextField;
|
||||||
|
use SilverStripe\SpamProtection\SpamProtector;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @package spamprotection
|
||||||
|
*/
|
||||||
|
class FooProtector implements SpamProtector, TestOnly
|
||||||
|
{
|
||||||
|
public function getFormField($name = null, $title = null, $value = null)
|
||||||
|
{
|
||||||
|
return new TextField($name, 'Foo', $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setFieldMapping($fieldMapping)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
23
tests/Stub/BarProtector.php
Normal file
23
tests/Stub/BarProtector.php
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace SilverStripe\SpamProtection\Tests\Stub;
|
||||||
|
|
||||||
|
use SilverStripe\Dev\TestOnly;
|
||||||
|
use SilverStripe\Forms\TextField;
|
||||||
|
use SilverStripe\SpamProtection\SpamProtector;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @package spamprotection
|
||||||
|
*/
|
||||||
|
class 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)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
22
tests/Stub/BazProtector.php
Normal file
22
tests/Stub/BazProtector.php
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace SilverStripe\SpamProtection\Tests\Stub;
|
||||||
|
|
||||||
|
use SilverStripe\Dev\TestOnly;
|
||||||
|
use SilverStripe\Forms\TextField;
|
||||||
|
use SilverStripe\SpamProtection\SpamProtector;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @package spamprotection
|
||||||
|
*/
|
||||||
|
class BazProtector implements SpamProtector, TestOnly
|
||||||
|
{
|
||||||
|
public function getFormField($name = null, $title = null, $value = null)
|
||||||
|
{
|
||||||
|
return new TextField($name, $title, $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setFieldMapping($fieldMapping)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
22
tests/Stub/FooProtector.php
Normal file
22
tests/Stub/FooProtector.php
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace SilverStripe\SpamProtection\Tests\Stub;
|
||||||
|
|
||||||
|
use SilverStripe\Dev\TestOnly;
|
||||||
|
use SilverStripe\Forms\TextField;
|
||||||
|
use SilverStripe\SpamProtection\SpamProtector;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @package spamprotection
|
||||||
|
*/
|
||||||
|
class FooProtector implements SpamProtector, TestOnly
|
||||||
|
{
|
||||||
|
public function getFormField($name = null, $title = null, $value = null)
|
||||||
|
{
|
||||||
|
return new TextField($name, 'Foo', $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setFieldMapping($fieldMapping)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
19
tests/Stub/Protector.php
Normal file
19
tests/Stub/Protector.php
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace SilverStripe\SpamProtection\Tests\Stub;
|
||||||
|
|
||||||
|
use SilverStripe\Dev\TestOnly;
|
||||||
|
use SilverStripe\Forms\TextField;
|
||||||
|
use SilverStripe\SpamProtection\SpamProtector;
|
||||||
|
|
||||||
|
class Protector implements SpamProtector, TestOnly
|
||||||
|
{
|
||||||
|
public function getFormField($name = null, $title = null, $value = null)
|
||||||
|
{
|
||||||
|
return new TextField($name, 'Foo', $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setFieldMapping($fieldMapping)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user