diff --git a/src/Control/HTTPRequest.php b/src/Control/HTTPRequest.php
index 7dfb4721f..8cc1ab915 100644
--- a/src/Control/HTTPRequest.php
+++ b/src/Control/HTTPRequest.php
@@ -463,9 +463,9 @@ class HTTPRequest implements ArrayAccess
* $this->setResponse(HTTPRequest::send_file('the content', 'filename.txt'));
*
* @static
- * @param $fileData
- * @param $fileName
- * @param null $mimeType
+ * @param string $fileData
+ * @param string $fileName
+ * @param string|null $mimeType
* @return HTTPResponse
*/
public static function send_file($fileData, $fileName, $mimeType = null)
@@ -497,7 +497,7 @@ class HTTPRequest implements ArrayAccess
* The pattern can optionally start with an HTTP method and a space. For example, "POST $Controller/$Action".
* This is used to define a rule that only matches on a specific HTTP method.
*
- * @param $pattern
+ * @param string $pattern
* @param bool $shiftOnSuccess
* @return array|bool
*/
@@ -679,7 +679,7 @@ class HTTPRequest implements ArrayAccess
}
/**
- * @param $params
+ * @param array $params
* @return HTTPRequest $this
*/
public function setRouteParams($params)
@@ -805,7 +805,7 @@ class HTTPRequest implements ArrayAccess
* Sets the client IP address which originated this request.
* Use setIPFromHeaderValue if assigning from header value.
*
- * @param $ip string
+ * @param string $ip
* @return $this
*/
public function setIP($ip)
diff --git a/src/Forms/FileUploadReceiver.php b/src/Forms/FileUploadReceiver.php
index 02c0e839d..19ed57d23 100644
--- a/src/Forms/FileUploadReceiver.php
+++ b/src/Forms/FileUploadReceiver.php
@@ -46,7 +46,7 @@ trait FileUploadReceiver
/**
* Parent data record. Will be inferred from parent form or controller if blank.
*
- * @var DataObject
+ * @var ?DataObject
*/
protected $record;
@@ -78,7 +78,7 @@ trait FileUploadReceiver
* Get the record to use as "Parent" for uploaded Files (eg a Page with a has_one to File) If none is set, it will
* use Form->getRecord() or Form->Controller()->data()
*
- * @return DataObject
+ * @return ?DataObject
*/
public function getRecord()
{
diff --git a/src/Forms/Form.php b/src/Forms/Form.php
index 6ded0bdef..111bbf120 100644
--- a/src/Forms/Form.php
+++ b/src/Forms/Form.php
@@ -370,7 +370,7 @@ class Form extends ViewableData implements HasRequestHandler
/**
* Helper to get current request for this form
*
- * @return HTTPRequest
+ * @return HTTPRequest|null
*/
protected function getRequest()
{
@@ -425,7 +425,7 @@ class Form extends ViewableData implements HasRequestHandler
/**
* Return any ValidationResult instance stored for this object
*
- * @return ValidationResult The ValidationResult object stored in the session
+ * @return ValidationResult|null The ValidationResult object stored in the session
*/
public function getSessionValidationResult()
{
@@ -1479,7 +1479,7 @@ class Form extends ViewableData implements HasRequestHandler
* It will make use of setCastedField() to do this.
*
* @param ViewableData&DataObjectInterface $dataObject The object to save data into
- * @param FieldList $fieldList An optional list of fields to process. This can be useful when you have a
+ * @param array|null $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.
*/
public function saveInto(DataObjectInterface $dataObject, $fieldList = null)
@@ -1610,7 +1610,7 @@ class Form extends ViewableData implements HasRequestHandler
* Return the default button that should be clicked when another one isn't
* available.
*
- * @return FormAction
+ * @return FormAction|null
*/
public function defaultAction()
{
diff --git a/src/Forms/NumericField.php b/src/Forms/NumericField.php
index 776ea381f..2e93e3e9c 100644
--- a/src/Forms/NumericField.php
+++ b/src/Forms/NumericField.php
@@ -101,10 +101,20 @@ class NumericField extends TextField
return NumberFormatter::TYPE_DOUBLE;
}
+ /**
+ * In some cases and locales, validation expects non-breaking spaces.
+ * This homogenises regular, narrow and thin non-breaking spaces to a regular space character.
+ *
+ */
+ private function clean(?string $value): string
+ {
+ return trim(str_replace(["\u{00A0}", "\u{202F}", "\u{2009}"], ' ', $value ?? ''));
+ }
+
public function setSubmittedValue($value, $data = null)
{
// Save original value in case parse fails
- $value = trim($value ?? '');
+ $value = $this->clean($value);
$this->originalValue = $value;
// Empty string is no-number (not 0)
diff --git a/src/ORM/DataList.php b/src/ORM/DataList.php
index e9dd06cde..902986668 100644
--- a/src/ORM/DataList.php
+++ b/src/ORM/DataList.php
@@ -356,7 +356,7 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li
*
* Raw SQL is not accepted, only actual field names can be passed
*
- * @param string|array $args
+ * @param string|array|null $args
* @example $list = $list->sort('Name'); // default ASC sorting
* @example $list = $list->sort('"Name"'); // field names can have double quotes around them
* @example $list = $list->sort('Name ASC, Age DESC');
diff --git a/tests/php/Forms/NumericFieldTest.php b/tests/php/Forms/NumericFieldTest.php
index 567d9a436..ca6a08af7 100644
--- a/tests/php/Forms/NumericFieldTest.php
+++ b/tests/php/Forms/NumericFieldTest.php
@@ -11,27 +11,6 @@ class NumericFieldTest extends SapphireTest
{
protected $usesDatabase = false;
- /**
- * In some cases and locales, validation expects non-breaking spaces.
- * This homogenises narrow and regular NBSPs to a regular space character
- *
- * Duplicates non-public NumericField::clean method
- *
- * @param string $input
- * @return string The input value, with all non-breaking spaces replaced with spaces
- */
- protected function clean($input)
- {
- return str_replace(
- [
- html_entity_decode(' ', 0, 'UTF-8'),
- html_entity_decode(' ', 0, 'UTF-8'), // narrow non-breaking space
- ],
- ' ',
- trim($input ?? '')
- );
- }
-
/**
* Test that data loaded in via Form::loadDataFrom(DataObject) will populate the field correctly,
* and can format the database value appropriately for the frontend
@@ -64,8 +43,8 @@ class NumericFieldTest extends SapphireTest
// Test expected formatted value
$this->assertEquals(
- $this->clean($output),
- $this->clean($field->Value()),
+ (string) $output,
+ $field->Value(),
"Expected $input to be formatted as $output in locale $locale"
);
@@ -92,11 +71,11 @@ class NumericFieldTest extends SapphireTest
['nl_NL', null, '12.1', '12,1'],
['nl_NL', 1, '14000.5', "14.000,5"],
// fr
- ['fr_FR', 0, '13000', "13 000"],
+ ['fr_FR', 0, '13000', "13 000"], // With a narrow non breaking space
['fr_FR', 0, '15', '15'],
['fr_FR', null, '12.0', '12,0'],
['fr_FR', null, '12.1', '12,1'],
- ['fr_FR', 1, '14000.5', "14 000,5"],
+ ['fr_FR', 1, '14000.5', "14 000,5"], // With a narrow non breaking space
// us
['en_US', 0, '13000', "13,000"],
['en_US', 0, '15', '15'],
@@ -172,15 +151,15 @@ class NumericFieldTest extends SapphireTest
['nl_NL', 1, '15,000.5', false],
// fr
- ['fr_FR', 0, '13000', 13000, '13 000'],
+ ['fr_FR', 0, '13000', 13000, '13 000'], // With a narrow non breaking space
['fr_FR', 2, '12,00', 12.0],
['fr_FR', 2, '12.00', false],
- ['fr_FR', 1, '11 000', 11000, '11 000,0'],
- ['fr_FR', 0, '11.000', 11000, '11 000'],
+ ['fr_FR', 1, '11 000', 11000, '11 000,0'], // With a narrow non breaking space
+ ['fr_FR', 0, '11.000', 11000, '11 000'], // With a narrow non breaking space
['fr_FR', null, '11,000', 11.000, '11,0'],
- ['fr_FR', 1, '15 000,5', 15000.5],
+ ['fr_FR', 1, '15 000,5', 15000.5, '15 000,5'], // With a narrow non breaking space
['fr_FR', 1, '15 000.5', false],
- ['fr_FR', 1, '15.000,5', 15000.5, '15 000,5'],
+ ['fr_FR', 1, '15.000,5', 15000.5, '15 000,5'], // With a narrow non breaking space
['fr_FR', 1, '15,000.5', false],
// us
['en_US', 0, '13000', 13000, '13,000'],
@@ -257,8 +236,8 @@ class NumericFieldTest extends SapphireTest
$cleanedInput = $submittedValue;
}
$this->assertEquals(
- $this->clean($cleanedInput),
- $this->clean($field->Value()),
+ $cleanedInput,
+ $field->Value(),
"Expected input $submittedValue to be cleaned up as $cleanedInput in locale $locale"
);
}