Skip to content

Commit 88ec777

Browse files
authored
Merge pull request #6438 from WoltLab/6.2-text-form-field-censorship
Add censorship support to text form fields
2 parents 9969630 + 3eb34af commit 88ec777

7 files changed

Lines changed: 105 additions & 11 deletions

File tree

wcfsetup/install/files/lib/form/ContactForm.class.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use wcf\system\form\builder\field\CaptchaFormField;
1616
use wcf\system\form\builder\field\EmailFormField;
1717
use wcf\system\form\builder\field\FileProcessorFormField;
18+
use wcf\system\form\builder\field\ICensorshipFormField;
1819
use wcf\system\form\builder\field\IFormField;
1920
use wcf\system\form\builder\field\SelectFormField;
2021
use wcf\system\form\builder\field\TextFormField;
@@ -51,6 +52,7 @@ protected function createForm()
5152
TextFormField::create('name')
5253
->label('wcf.contact.sender')
5354
->required()
55+
->censorship()
5456
->value(WCF::getUser()->username ?: ''),
5557
EmailFormField::create('email')
5658
->label('wcf.user.email')
@@ -226,6 +228,10 @@ protected function getOptionFormFields(): array
226228
$formField->required();
227229
}
228230

231+
if ($formField instanceof ICensorshipFormField) {
232+
$formField->censorship();
233+
}
234+
229235
$formFields[] = $formField;
230236
}
231237

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
namespace wcf\system\form\builder\field;
4+
5+
/**
6+
* Represents a form field that supports the use of the censorship function.
7+
*
8+
* @author Marcel Werk
9+
* @copyright 2001-2025 WoltLab GmbH
10+
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
11+
* @since 6.2
12+
*/
13+
interface ICensorshipFormField extends IFormField
14+
{
15+
/**
16+
* Sets whether the censorship function should be applied to this field.
17+
*/
18+
public function censorship(bool $censorship = true): static;
19+
20+
/**
21+
* Returns `true` if the censorship function should be applied to this field.
22+
*/
23+
public function hasCensorship(): bool;
24+
25+
/**
26+
* Validates whether the text contains censored words.
27+
*/
28+
public function validateCensorship(string $text): void;
29+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<?php
2+
3+
namespace wcf\system\form\builder\field;
4+
5+
use wcf\system\form\builder\field\validation\FormFieldValidationError;
6+
use wcf\system\message\censorship\Censorship;
7+
8+
/**
9+
* Provides default implementations of `ICensorshipFormField` methods.
10+
*
11+
* @author Marcel Werk
12+
* @copyright 2001-2025 WoltLab GmbH
13+
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
14+
* @since 6.2
15+
*/
16+
trait TCensorshipFormField
17+
{
18+
protected bool $censorship = false;
19+
20+
#[\Override]
21+
public function censorship(bool $censorship = true): static
22+
{
23+
$this->censorship = $censorship;
24+
25+
return $this;
26+
}
27+
28+
#[\Override]
29+
public function hasCensorship(): bool
30+
{
31+
return $this->censorship;
32+
}
33+
34+
#[\Override]
35+
public function validateCensorship(string $text): void
36+
{
37+
if (!$this->hasCensorship()) {
38+
return;
39+
}
40+
41+
if (!($this instanceof IFormField)) {
42+
return;
43+
}
44+
45+
$censoredWords = Censorship::getInstance()->test($text);
46+
if ($censoredWords) {
47+
$this->addValidationError(new FormFieldValidationError(
48+
'censoredWords',
49+
'wcf.message.error.censoredWordsFound',
50+
['censoredWords' => $censoredWords]
51+
));
52+
}
53+
}
54+
}

wcfsetup/install/files/lib/system/form/builder/field/TextFormField.class.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ class TextFormField extends AbstractFormField implements
1818
IAttributeFormField,
1919
IAutoCompleteFormField,
2020
IAutoFocusFormField,
21+
ICensorshipFormField,
2122
ICssClassFormField,
2223
II18nFormField,
2324
IImmutableFormField,
@@ -30,6 +31,7 @@ class TextFormField extends AbstractFormField implements
3031
use TInputAttributeFormField;
3132
use TTextAutoCompleteFormField;
3233
use TAutoFocusFormField;
34+
use TCensorshipFormField;
3335
use TCssClassFormField;
3436
use TImmutableFormField;
3537
use TInputModeFormField;
@@ -115,6 +117,7 @@ protected function validateText($text, ?Language $language = null)
115117
{
116118
$this->validateMinimumLength($text, $language);
117119
$this->validateMaximumLength($text, $language);
120+
$this->validateCensorship($text);
118121
}
119122

120123
/**

wcfsetup/install/files/lib/system/form/builder/field/wysiwyg/WysiwygFormField.class.php

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@
66
use wcf\system\form\builder\data\processor\CustomFormDataProcessor;
77
use wcf\system\form\builder\field\AbstractFormField;
88
use wcf\system\form\builder\field\IAttributeFormField;
9+
use wcf\system\form\builder\field\ICensorshipFormField;
910
use wcf\system\form\builder\field\IMaximumLengthFormField;
1011
use wcf\system\form\builder\field\IMinimumLengthFormField;
12+
use wcf\system\form\builder\field\TCensorshipFormField;
1113
use wcf\system\form\builder\field\TInputAttributeFormField;
1214
use wcf\system\form\builder\field\TMaximumLengthFormField;
1315
use wcf\system\form\builder\field\TMinimumLengthFormField;
@@ -17,7 +19,6 @@
1719
use wcf\system\form\builder\TObjectTypeFormNode;
1820
use wcf\system\html\input\HtmlInputProcessor;
1921
use wcf\system\html\upcast\HtmlUpcastProcessor;
20-
use wcf\system\message\censorship\Censorship;
2122
use wcf\system\message\quote\MessageQuoteManager;
2223
use wcf\system\WCF;
2324
use wcf\util\StringUtil;
@@ -32,10 +33,12 @@
3233
*/
3334
final class WysiwygFormField extends AbstractFormField implements
3435
IAttributeFormField,
36+
ICensorshipFormField,
3537
IMaximumLengthFormField,
3638
IMinimumLengthFormField,
3739
IObjectTypeFormNode
3840
{
41+
use TCensorshipFormField;
3942
use TInputAttributeFormField {
4043
getReservedFieldAttributes as private inputGetReservedFieldAttributes;
4144
}
@@ -89,6 +92,12 @@ final class WysiwygFormField extends AbstractFormField implements
8992
*/
9093
protected $templateName = 'shared_wysiwygFormField';
9194

95+
public function __construct()
96+
{
97+
// WYSIWYG form fields use the censorship function by default for backward compatibility reasons.
98+
$this->censorship();
99+
}
100+
92101
/**
93102
* Sets the identifier used to autosave the field value and returns this field.
94103
*
@@ -372,14 +381,7 @@ public function validate()
372381
$this->validateMaximumLength($message);
373382

374383
if (empty($this->getValidationErrors())) {
375-
$censoredWords = Censorship::getInstance()->test($message);
376-
if ($censoredWords) {
377-
$this->addValidationError(new FormFieldValidationError(
378-
'censoredWords',
379-
'wcf.message.error.censoredWordsFound',
380-
['censoredWords' => $censoredWords]
381-
));
382-
}
384+
$this->validateCensorship($message);
383385
}
384386
}
385387
}

wcfsetup/install/lang/de.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4341,7 +4341,7 @@ Erlaubte Dateiendungen: gif, jpg, jpeg, png, webp]]></item>
43414341
<item name="wcf.message.button.extendedReply"><![CDATA[Erweiterte Antwort]]></item>
43424342
<item name="wcf.message.button.extendedEdit"><![CDATA[Erweiterte Bearbeitung]]></item>
43434343
<item name="wcf.message.new"><![CDATA[Neu]]></item>
4344-
<item name="wcf.message.error.censoredWordsFound"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Deine{else}Ihre{/if} Nachricht verwendet nicht gestattete Begriffe: {implode from=$censoredWords key=censoredWord item=number}{$censoredWord}{if $number > 1} ({#$number}×){/if}{/implode}]]></item>
4344+
<item name="wcf.message.error.censoredWordsFound"><![CDATA[Der Text verwendet nicht gestattete Begriffe: {implode from=$censoredWords key=censoredWord item=number}{$censoredWord}{if $number > 1} ({#$number}×){/if}{/implode}]]></item>
43454345
<item name="wcf.message.error.disallowedBBCodes"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Deine{else}Ihre{/if} Nachricht enthält die folgenden BBCodes, die {if LANGUAGE_USE_INFORMAL_VARIANT}du nicht verwenden darfst{else}Sie nicht verwenden dürfen{/if}: {implode from=$disallowedBBCodes item=disallowedBBCode}{$disallowedBBCode}{/implode}]]></item>
43464346
<item name="wcf.message.error.editorAlreadyInUse"><![CDATA[Der Editor ist bereits aktiv, {if LANGUAGE_USE_INFORMAL_VARIANT}beende die Bearbeitung bevor du fortfährst{else}beenden Sie die Bearbeitung bevor Sie fortfahren{/if}.]]></item>
43474347
<item name="wcf.message.error.tooLong"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Deine{else}Ihre{/if} Nachricht ist zu lang. Es stehen maximal {#$maxTextLength} Zeichen zur Verfügung.]]></item>

wcfsetup/install/lang/en.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4287,7 +4287,7 @@ Allowed extensions: gif, jpg, jpeg, png, webp]]></item>
42874287
<item name="wcf.message.button.extendedReply"><![CDATA[More Options]]></item>
42884288
<item name="wcf.message.button.extendedEdit"><![CDATA[More Options]]></item>
42894289
<item name="wcf.message.new"><![CDATA[New]]></item>
4290-
<item name="wcf.message.error.censoredWordsFound"><![CDATA[The message contains disallowed words: {implode from=$censoredWords key=censoredWord item=number}{$censoredWord}{if $number > 1} ({#$number}×){/if}{/implode}.]]></item>
4290+
<item name="wcf.message.error.censoredWordsFound"><![CDATA[The text contains disallowed words: {implode from=$censoredWords key=censoredWord item=number}{$censoredWord}{if $number > 1} ({#$number}×){/if}{/implode}.]]></item>
42914291
<item name="wcf.message.error.disallowedBBCodes"><![CDATA[The message contains disallowed BBCodes: {implode from=$disallowedBBCodes item=disallowedBBCode}{$disallowedBBCode}{/implode}.]]></item>
42924292
<item name="wcf.message.error.editorAlreadyInUse"><![CDATA[The editor is already in use, please finish editing before continuing.]]></item>
42934293
<item name="wcf.message.error.tooLong"><![CDATA[The message is too long, must be under {#$maxTextLength} characters.]]></item>

0 commit comments

Comments
 (0)