1
0
mirror of https://github.com/processwire/processwire.git synced 2025-08-17 12:10:45 +02:00

Update FieldtypeText to automatically add "HTML Entity Encoder" textformatter to newly created text fields (and descending types). Also update it to add warning when editing an existing field and it allows HTML in formatted output, and we aren't sure that's intended. Lastly, update FieldtypeTextarea to identify when the HTML Entity Encoder has been added to a field where HTML is clearly intended and warn the user that they should remove that from the Text formatters. (This is necessary since it may have been automatically added when the field was created.)

This commit is contained in:
Ryan Cramer
2023-02-09 10:49:06 -05:00
parent 1171241f5d
commit b289cb03aa
3 changed files with 64 additions and 14 deletions

View File

@@ -8,7 +8,7 @@
* For documentation about the fields used in this class, please see:
* /wire/core/Fieldtype.php
*
* ProcessWire 3.x, Copyright 2022 by Ryan Cramer
* ProcessWire 3.x, Copyright 2023 by Ryan Cramer
* https://processwire.com
*
*
@@ -131,6 +131,7 @@ class FieldtypeText extends Fieldtype {
public function getInputfield(Page $page, Field $field) {
$modules = $this->wire()->modules;
$inputfieldClass = $field->get('inputfieldClass');
/** @var Inputfield $inputfield */
$inputfield = $inputfieldClass ? $modules->getModule($inputfieldClass) : null;
if(!$inputfield) $inputfield = $modules->get('InputfieldText');
return $inputfield;
@@ -169,6 +170,24 @@ class FieldtypeText extends Fieldtype {
return $schema;
}
/**
* Hook called when field is about to be saved
*
* @param Field $field
* @since 3.0.212
*
*/
public function ___saveFieldReady(Field $field) {
parent::___saveFieldReady($field);
if(!$field->id && $this->allowTextFormatters() && $this->wire()->page->process == 'ProcessField') {
// default Textformatter for newly created fields in ProcessField
$value = $field->get('textformatters');
if(!is_array($value) || !count($value)) {
$field->set('textformatters', array('TextformatterEntities'));
}
}
}
/**
* Return the fields required to configure an instance of FieldtypeText
*
@@ -212,9 +231,32 @@ class FieldtypeText extends Fieldtype {
$f->notes =
$this->_('For plain text fields that will not contain HTML or markup, we recommend selecting the **HTML Entity Encoder** option above.');
$fieldset->add($f);
if(!in_array('TextformatterEntities', $value) && $this->allowTextformatters() && !$this->wire()->input->is('post')) {
// warn user when HTML is allowed and we arent sure they intend to allow it
$allowHTML = false;
if(wireInstanceOf($field->type, 'FieldtypeTextarea')) {
$inputType = $field->get('inputfieldClass');
$htmlInputTypes = array('InputfieldTinyMCE', 'InputfieldCKEditor');
$contentType = $field->get('contentType');
$allowHTML = in_array($inputType, $htmlInputTypes) || $contentType >= FieldtypeTextarea::contentTypeHTML;
}
if(!$allowHTML) {
$htmlValue = '<p>HTML</p>';
foreach($value as $textformatter) {
/** @var Textformatter $textformatter */
$textformatter = $modules->get($textformatter);
if($textformatter) $textformatter->format($htmlValue);
}
if(strpos($htmlValue, '<') !== false) $this->warning(
$this->_('This field currently allows Markup/HTML in formatted output.') . ' ' .
$this->_('If you do not intend to allow Markup/HTML, please select the “HTML Entity Encoder” for “Text formatters”.')
);
}
}
if($field->type->className() === 'FieldtypeText') {
/** @var InputfieldSelect $field */
/** @var InputfieldSelect $f */
$defaultLabel = $this->_('Default');
$f = $modules->get('InputfieldRadios');
$f->attr('name', 'inputfieldClass');

View File

@@ -8,7 +8,7 @@
* For documentation about the fields used in this class, please see:
* /wire/core/Fieldtype.php
*
* ProcessWire 3.x, Copyright 2022 by Ryan Cramer
* ProcessWire 3.x, Copyright 2023 by Ryan Cramer
* https://processwire.com
*
* Properties set to $field that is using this type, acceessed by $field->get('property'):
@@ -101,10 +101,6 @@ class FieldtypeTextarea extends FieldtypeText {
parent::init();
}
public function sanitizeValue(Page $page, Field $field, $value) {
return parent::sanitizeValue($page, $field, $value);
}
public function ___markupValue(Page $page, Field $field, $value = null, $property = '') {
if(is_null($value)) $value = $page->getFormatted($field->name);
if($field->get('contentType') >= self::contentTypeHTML) {
@@ -203,13 +199,12 @@ class FieldtypeTextarea extends FieldtypeText {
$value[$k] = $v;
}
} else if(is_object($value) && $languages && $value instanceof LanguagesValueInterface && $value instanceof Wire) {
} else if($languages && $value instanceof LanguagesValueInterface) {
// most likely a LanguagesPageFieldValue, but can be any type implementing LanguagesValueInterface
/** @var Wire|LanguagesValueInterface $value */
$trackChanges = $value->trackChanges();
$value->setTrackChanges(false);
foreach($languages as $language) {
/** @var LanguagesValueInterface $value */
$v = $value->getLanguageValue($language->id);
$this->_htmlReplacement($page, $field, $v, $sleep);
$value->setLanguageValue($language, $v);

View File

@@ -3,7 +3,7 @@
/**
* Helper class for FieldtypeTextarea configuration
*
* ProcessWire 3.x, Copyright 2022 by Ryan Cramer
* ProcessWire 3.x, Copyright 2023 by Ryan Cramer
* https://processwire.com
*
*/
@@ -29,6 +29,20 @@ class FieldtypeTextareaHelper extends Wire {
function getConfigInputfields(Field $field, InputfieldWrapper $inputfields) {
$modules = $this->wire()->modules;
$f = $inputfields->getChildByName('textformatters');
if($f && !$this->wire()->input->is('post')) {
$htmlInputTypes = array('InputfieldCKEditor', 'InputfieldTinyMCE');
$inputType = $field->get('inputfieldClass');
$contentType = $field->get('contentType');
if($contentType >= FieldtypeTextarea::contentTypeHTML || in_array($inputType, $htmlInputTypes)) {
$value = $field->get('textformatters');
$key = is_array($value) ? array_search('TextformatterEntities', $value) : false;
if($key !== false) {
$field->warning($this->_('Please remove “HTML Entity Encoder” from “Text formatters” since this field allows Markup/HTML.'));
}
}
}
$value = $field->get('inputfieldClass');
/** @var InputfieldSelect $f */
$f = $modules->get('InputfieldSelect');
@@ -39,7 +53,7 @@ class FieldtypeTextareaHelper extends Wire {
$f->required = true;
$baseClass = "InputfieldTextarea";
foreach($this->wire('modules')->find("className^=Inputfield") as $fm) {
foreach($modules->find("className^=Inputfield") as $fm) {
if("$fm" == $baseClass || is_subclass_of($fm->className(true), __NAMESPACE__ . "\\$baseClass")) {
$f->addOption("$fm", str_replace("Inputfield", '', "$fm"));
}
@@ -144,7 +158,6 @@ class FieldtypeTextareaHelper extends Wire {
*
*/
public function applyFieldHTML(HookEvent $event) {
if($event) {} // ignore
$pages = $this->wire()->pages;
$config = $this->wire()->config;
@@ -152,7 +165,7 @@ class FieldtypeTextareaHelper extends Wire {
set_time_limit(3600);
$field = $this->applyFieldHTML;
if(!$field || !$field instanceof Field || !$field->type instanceof FieldtypeTextarea) return;
if(!$field instanceof Field || !$field->type instanceof FieldtypeTextarea) return;
$selector = "$field->name%=href|src, include=all";
$total = $pages->count($selector);
@@ -285,4 +298,4 @@ class FieldtypeTextareaHelper extends Wire {
Notice::allowMarkup);
}
}
}
}