From 13230ed7f34707903eb5a6926e5cf7ecfccc9595 Mon Sep 17 00:00:00 2001 From: Shamim Rezaie Date: Wed, 23 Jan 2019 15:55:04 +1100 Subject: [PATCH] MDL-53140 core: Introduced PARAM_LOCALISEDFLOAT --- lib/moodlelib.php | 17 ++++++++++++----- lib/tests/moodlelib_test.php | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 5 deletions(-) diff --git a/lib/moodlelib.php b/lib/moodlelib.php index 321560d3856..42e5ca1fcea 100644 --- a/lib/moodlelib.php +++ b/lib/moodlelib.php @@ -137,14 +137,17 @@ define('PARAM_FILE', 'file'); * * Note that you should not use PARAM_FLOAT for numbers typed in by the user. * It does not work for languages that use , as a decimal separator. - * Instead, do something like - * $rawvalue = required_param('name', PARAM_RAW); - * // ... other code including require_login, which sets current lang ... - * $realvalue = unformat_float($rawvalue); - * // ... then use $realvalue + * Use PARAM_LOCALISEDFLOAT instead. */ define('PARAM_FLOAT', 'float'); +/** + * PARAM_LOCALISEDFLOAT - a localised real/floating point number. + * This is preferred over PARAM_FLOAT for numbers typed in by the user. + * Cleans localised numbers to computer readable numbers; false for invalid numbers. + */ +define('PARAM_LOCALISEDFLOAT', 'localisedfloat'); + /** * PARAM_HOST - expected fully qualified domain name (FQDN) or an IPv4 dotted quad (IP address) */ @@ -843,6 +846,10 @@ function clean_param($param, $type) { // Convert to float. return (float)$param; + case PARAM_LOCALISEDFLOAT: + // Convert to float. + return unformat_float($param, true); + case PARAM_ALPHA: // Remove everything not `a-z`. return preg_replace('/[^a-zA-Z]/i', '', $param); diff --git a/lib/tests/moodlelib_test.php b/lib/tests/moodlelib_test.php index db9ce6d793b..f27a6f59d9e 100644 --- a/lib/tests/moodlelib_test.php +++ b/lib/tests/moodlelib_test.php @@ -525,6 +525,38 @@ class core_moodlelib_testcase extends advanced_testcase { $this->assertSame('', clean_param('user_', PARAM_COMPONENT)); } + public function test_clean_param_localisedfloat() { + + $this->assertSame(0.5, clean_param('0.5', PARAM_LOCALISEDFLOAT)); + $this->assertSame(false, clean_param('0X5', PARAM_LOCALISEDFLOAT)); + $this->assertSame(0.5, clean_param('.5', PARAM_LOCALISEDFLOAT)); + $this->assertSame(false, clean_param('X5', PARAM_LOCALISEDFLOAT)); + $this->assertSame(10.5, clean_param('10.5', PARAM_LOCALISEDFLOAT)); + $this->assertSame(false, clean_param('10X5', PARAM_LOCALISEDFLOAT)); + $this->assertSame(1000.5, clean_param('1 000.5', PARAM_LOCALISEDFLOAT)); + $this->assertSame(false, clean_param('1 000X5', PARAM_LOCALISEDFLOAT)); + $this->assertSame(false, clean_param('1.000.5', PARAM_LOCALISEDFLOAT)); + $this->assertSame(false, clean_param('1X000X5', PARAM_LOCALISEDFLOAT)); + $this->assertSame(false, clean_param('nan', PARAM_LOCALISEDFLOAT)); + $this->assertSame(false, clean_param('10.6blah', PARAM_LOCALISEDFLOAT)); + + // Tests with a localised decimal separator. + $this->define_local_decimal_separator(); + + $this->assertSame(0.5, clean_param('0.5', PARAM_LOCALISEDFLOAT)); + $this->assertSame(0.5, clean_param('0X5', PARAM_LOCALISEDFLOAT)); + $this->assertSame(0.5, clean_param('.5', PARAM_LOCALISEDFLOAT)); + $this->assertSame(0.5, clean_param('X5', PARAM_LOCALISEDFLOAT)); + $this->assertSame(10.5, clean_param('10.5', PARAM_LOCALISEDFLOAT)); + $this->assertSame(10.5, clean_param('10X5', PARAM_LOCALISEDFLOAT)); + $this->assertSame(1000.5, clean_param('1 000.5', PARAM_LOCALISEDFLOAT)); + $this->assertSame(1000.5, clean_param('1 000X5', PARAM_LOCALISEDFLOAT)); + $this->assertSame(false, clean_param('1.000.5', PARAM_LOCALISEDFLOAT)); + $this->assertSame(false, clean_param('1X000X5', PARAM_LOCALISEDFLOAT)); + $this->assertSame(false, clean_param('nan', PARAM_LOCALISEDFLOAT)); + $this->assertSame(false, clean_param('10X6blah', PARAM_LOCALISEDFLOAT)); + } + public function test_is_valid_plugin_name() { $this->assertTrue(is_valid_plugin_name('forum')); $this->assertTrue(is_valid_plugin_name('forum2'));