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" ); }