API Add FormField::canSubmitValue()

API Add HTMLText::getProcessShortcodes() / setProcessShortcodes()
API Split TextareaField::Value() into ValueEntities() with shortcodes disabled
This commit is contained in:
Damian Mooyman 2016-11-15 13:34:54 +13:00
parent 8e5f786b8d
commit f43a91a4f8
8 changed files with 96 additions and 44 deletions

View File

@ -47,7 +47,7 @@ class SapphireTest extends PHPUnit_Framework_TestCase {
* @deprecated since version 4.0
*/
protected $originalMailer;
protected $originalMemberPasswordValidator;
protected $originalRequirements;
protected $originalIsRunningTest;
@ -191,9 +191,9 @@ class SapphireTest extends PHPUnit_Framework_TestCase {
self::$is_running_test = true;
// i18n needs to be set to the defaults or tests fail
i18n::set_locale(i18n::default_locale());
i18n::config()->date_format = null;
i18n::config()->time_format = null;
i18n::set_locale(i18n::config()->default_locale);
i18n::config()->date_format = 'yyyy-MM-dd';
i18n::config()->time_format = 'H:mm';
// Set default timezone consistently to avoid NZ-specific dependencies
date_default_timezone_set('UTC');
@ -217,7 +217,7 @@ class SapphireTest extends PHPUnit_Framework_TestCase {
Config::inst()->update('Director', 'rules', array(
'$Controller//$Action/$ID/$OtherID' => '*'
));
$fixtureFile = static::get_fixture_file();
$prefix = defined('SS_DATABASE_PREFIX') ? SS_DATABASE_PREFIX : 'ss_';
@ -367,7 +367,7 @@ class SapphireTest extends PHPUnit_Framework_TestCase {
}
}
}
//unnest injector / config now that the test suite is over
// this will reset all the extensions on the object too (see setUpOnce)
Injector::unnest();
@ -719,22 +719,22 @@ class SapphireTest extends PHPUnit_Framework_TestCase {
. var_export($match, true) . ": " . var_export($item, true)
);
}
}
}
/**
* Removes sequences of repeated whitespace characters from SQL queries
* making them suitable for string comparison
*
*
* @param string $sql
* @return string The cleaned and normalised SQL string
*/
protected function normaliseSQL($sql) {
return trim(preg_replace('/\s+/m', ' ', $sql));
}
/**
* Asserts that two SQL queries are equivalent
*
*
* @param string $expectedSQL
* @param string $actualSQL
* @param string $message
@ -749,7 +749,7 @@ class SapphireTest extends PHPUnit_Framework_TestCase {
// Normalise SQL queries to remove patterns of repeating whitespace
$expectedSQL = $this->normaliseSQL($expectedSQL);
$actualSQL = $this->normaliseSQL($actualSQL);
$this->assertEquals($expectedSQL, $actualSQL, $message, $delta, $maxDepth, $canonicalize, $ignoreCase);
}
@ -813,7 +813,7 @@ class SapphireTest extends PHPUnit_Framework_TestCase {
public static function using_temp_db() {
$dbConn = DB::get_conn();
$prefix = defined('SS_DATABASE_PREFIX') ? SS_DATABASE_PREFIX : 'ss_';
return $dbConn && (substr($dbConn->getSelectedDatabase(), 0, strlen($prefix) + 5)
return $dbConn && (substr($dbConn->getSelectedDatabase(), 0, strlen($prefix) + 5)
== strtolower(sprintf('%stmpdb', $prefix)));
}
@ -919,7 +919,7 @@ class SapphireTest extends PHPUnit_Framework_TestCase {
if(!($SNG instanceof TestOnly)) $SNG->requireTable();
}
}
// If we have additional dataobjects which need schema, do so here:
if($extraDataObjects) {
foreach($extraDataObjects as $dataClass) {
@ -997,7 +997,7 @@ class SapphireTest extends PHPUnit_Framework_TestCase {
// Remove all the test themes we created
SS_TemplateLoader::instance()->popManifest();
Config::unnest();
if ($e) throw $e;

View File

@ -47,14 +47,23 @@ class FieldList extends ArrayList {
/**
* Return a sequential set of all fields that have data. This excludes wrapper composite fields
* as well as heading / help text fields.
*
* @return array
*/
public function dataFields() {
if(!$this->sequentialSet) $this->collateDataFields($this->sequentialSet);
if(!$this->sequentialSet) {
$this->collateDataFields($this->sequentialSet);
}
return $this->sequentialSet;
}
/**
* @return array
*/
public function saveableFields() {
if(!$this->sequentialSaveableSet) $this->collateDataFields($this->sequentialSaveableSet, true);
if(!$this->sequentialSaveableSet) {
$this->collateDataFields($this->sequentialSaveableSet, true);
}
return $this->sequentialSaveableSet;
}
@ -64,13 +73,20 @@ class FieldList extends ArrayList {
}
protected function collateDataFields(&$list, $saveableOnly = false) {
// Initialise list
if (!isset($list)) {
$list = array();
}
/** @var FormField $field */
foreach($this as $field) {
if($field->isComposite()) $field->collateDataFields($list, $saveableOnly);
if($field->isComposite()) {
$field->collateDataFields($list, $saveableOnly);
}
if($saveableOnly) {
$isIncluded = ($field->hasData() && !$field->isReadonly() && !$field->isDisabled());
$isIncluded = $field->canSubmitValue();
} else {
$isIncluded = ($field->hasData());
$isIncluded = $field->hasData();
}
if($isIncluded) {
$name = $field->getName();

View File

@ -355,18 +355,8 @@ class Form extends RequestHandler {
$vars = $request->requestVars();
}
// construct an array of allowed fields that can be populated from request data.
// readonly or disabled fields should not be loading data from requests
$allowedFields = array();
$dataFields = $this->Fields()->dataFields();
if ($dataFields) {
/** @var FormField $field */
foreach ($this->Fields()->dataFields() as $name => $field) {
if (!$field->isReadonly() && !$field->isDisabled()) {
$allowedFields[] = $name;
}
}
}
// Ensure we only process saveable fields (non structural, readonly, or disabled)
$allowedFields = array_keys($this->Fields()->saveableFields());
// Populate the form
$this->loadDataFrom($vars, true, $allowedFields);
@ -1392,7 +1382,7 @@ class Form extends RequestHandler {
* For backwards compatibility reasons, this parameter can also be set to === true, which is the same as passing
* CLEAR_MISSING
*
* @param FieldList $fieldList An optional list of fields to process. This can be useful when you have a
* @param array $fieldList An optional list of fields to process. This can be useful when you have a
* form that has some fields that save to one object, and some that save to another.
* @return Form
*/
@ -1669,7 +1659,7 @@ class Form extends RequestHandler {
/**
* Get a list of all actions, including those in the main "fields" FieldList
*
*
* @return array
*/
protected function getAllActions() {

View File

@ -1277,4 +1277,13 @@ class FormField extends RequestHandler {
return $field;
}
/**
* Determine if the value of this formfield accepts front-end submitted values and is saveable.
*
* @return bool
*/
public function canSubmitValue() {
return $this->hasData() && !$this->isReadonly() && !$this->isDisabled();
}
}

View File

@ -26,14 +26,6 @@ class HtmlEditorField extends TextareaField {
*/
private static $sanitise_server_side = false;
/**
* @config
* @var array
*/
private static $casting = array(
'Value' => 'HTMLText',
);
protected $rows = 30;
/**

View File

@ -19,8 +19,13 @@
*/
class TextareaField extends FormField {
/**
* Value should be XML
*
* @var array
*/
private static $casting = array(
'Value' => 'HTMLText',
'Value' => 'HTMLText(array(\'shortcodes\' => false))',
);
/**
@ -93,7 +98,9 @@ class TextareaField extends FormField {
}
/**
* @return string
* Return value with all values encoded in html entities
*
* @return string Raw HTML
*/
public function Value() {
return htmlentities($this->value, ENT_COMPAT, 'UTF-8');

View File

@ -34,6 +34,26 @@ class HTMLText extends Text {
protected $processShortcodes = true;
/**
* Check if shortcodes are enabled
*
* @return bool
*/
public function getProcessShortcodes() {
return $this->processShortcodes;
}
/**
* Set shortcodes on or off by default
*
* @param bool $process
* @return $this
*/
public function setProcessShortcodes($process) {
$this->processShortcodes = (bool)$process;
return $this;
}
protected $whitelist = false;
public function __construct($name = null, $options = array()) {

View File

@ -16,7 +16,7 @@ class TextareaFieldTest extends SapphireTest {
/**
* Quick smoke test to ensure that text with special html chars is being displayed properly in readonly fields.
*/
public function testReadonlyDisplaySepcialHTML() {
public function testReadonlyDisplaySpecialHTML() {
$inputText = "These are some special <html> chars including 'single' & \"double\" quotations";
$field = new TextareaField("Test", "Test");
$field = $field->performReadonlyTransformation();
@ -25,4 +25,22 @@ class TextareaFieldTest extends SapphireTest {
. ' &quot;double&quot; quotations', $field->Field());
}
public function testValueEntities() {
$inputText = "These <b>are</b> some unicodes: äöü";
$field = new TextareaField("Test", "Test");
$field->setValue($inputText);
// Value should be safe-encoding only, but ValueEntities should be more aggressive
$this->assertEquals(
"These &lt;b&gt;are&lt;/b&gt; some unicodes: &auml;&ouml;&uuml;",
$field->obj('Value')->forTemplate()
);
// Shortcodes are disabled
$this->assertEquals(
false,
$field->obj('Value')->getProcessShortcodes()
);
}
}