Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge branch 'MDL-38239-moodle25' of git://github.com/StudiUM/moodle …

…into MOODLE_25_STABLE
  • Loading branch information...
commit 121e2492e80046102ed68ebc884cd5e5e4bf12ef 2 parents 6c16494 + f7d180a
@danpoltawski danpoltawski authored
View
25 grade/import/csv/index.php
@@ -351,16 +351,21 @@
$newgrade->finalgrade = $value;
} else {
if ($value === '' or $value == '-') {
- $value = null; // no grade
-
- } else if (!is_numeric($value)) {
- // non numeric grade value supplied, possibly mapped wrong column
- echo "<br/>t0 is $t0";
- echo "<br/>grade is $value";
- $status = false;
- import_cleanup($importcode);
- echo $OUTPUT->notification(get_string('badgrade', 'grades'));
- break 3;
+ $value = null; // No grade.
+ } else {
+ // If the value has a local decimal or can correctly be unformatted, do it.
+ $validvalue = unformat_float($value, true);
+ if ($validvalue !== false) {
+ $value = $validvalue;
+ } else {
+ // Non numeric grade value supplied, possibly mapped wrong column.
+ echo "<br/>t0 is $t0";
+ echo "<br/>grade is $value";
+ $status = false;
+ import_cleanup($importcode);
+ echo $OUTPUT->notification(get_string('badgrade', 'grades'));
+ break 3;
+ }
}
$newgrade->finalgrade = $value;
}
View
12 lib/moodlelib.php
@@ -9670,9 +9670,10 @@ function format_float($float, $decimalpoints=1, $localized=true, $stripzeros=fal
* Do NOT try to do any math operations before this conversion on any user submitted floats!
*
* @param string $locale_float locale aware float representation
- * @return float
+ * @param bool $strict If true, then check the input and return false if it is not a valid number.
+ * @return mixed float|bool - false or the parsed float.
*/
-function unformat_float($locale_float) {
+function unformat_float($locale_float, $strict = false) {
$locale_float = trim($locale_float);
if ($locale_float == '') {
@@ -9680,8 +9681,13 @@ function unformat_float($locale_float) {
}
$locale_float = str_replace(' ', '', $locale_float); // no spaces - those might be used as thousand separators
+ $locale_float = str_replace(get_string('decsep', 'langconfig'), '.', $locale_float);
+
+ if ($strict && !is_numeric($locale_float)) {
+ return false;
+ }
- return (float)str_replace(get_string('decsep', 'langconfig'), '.', $locale_float);
+ return (float)$locale_float;
}
/**
View
111 lib/tests/moodlelib_test.php
@@ -85,6 +85,29 @@ class moodlelib_testcase extends advanced_testcase {
)
);
+ /**
+ * Define a local decimal separator.
+ *
+ * It is not possible to directly change the result of get_string in
+ * a unit test. Instead, we create a language pack for language 'xx' in
+ * dataroot and make langconfig.php with the string we need to change.
+ * The example separator used here is 'X'; on PHP 5.3 and before this
+ * must be a single byte character due to PHP bug/limitation in
+ * number_format, so you can't use UTF-8 characters.
+ *
+ * @global type $SESSION
+ * @global type $CFG
+ */
+ protected function define_local_decimal_separator() {
+ global $SESSION, $CFG;
+
+ $SESSION->lang = 'xx';
+ $langconfig = "<?php\n\$string['decsep'] = 'X';";
+ $langfolder = $CFG->dataroot . '/lang/xx';
+ check_dir_exists($langfolder);
+ file_put_contents($langfolder . '/langconfig.php', $langconfig);
+ }
+
function test_cleanremoteaddr() {
//IPv4
$this->assertEquals(cleanremoteaddr('1023.121.234.1'), null);
@@ -2122,7 +2145,6 @@ public function test_get_string_limitation() {
* Test localised float formatting.
*/
public function test_format_float() {
- global $SESSION, $CFG;
// Special case for null
$this->assertEquals('', format_float(null));
@@ -2138,17 +2160,8 @@ public function test_format_float() {
$this->assertEquals('5.43', format_float(5.43, 5, true, true));
$this->assertEquals('5', format_float(5.0001, 3, true, true));
- // It is not possible to directly change the result of get_string in
- // a unit test. Instead, we create a language pack for language 'xx' in
- // dataroot and make langconfig.php with the string we need to change.
- // The example separator used here is 'X'; on PHP 5.3 and before this
- // must be a single byte character due to PHP bug/limitation in
- // number_format, so you can't use UTF-8 characters.
- $SESSION->lang = 'xx';
- $langconfig = "<?php\n\$string['decsep'] = 'X';";
- $langfolder = $CFG->dataroot . '/lang/xx';
- check_dir_exists($langfolder);
- file_put_contents($langfolder . '/langconfig.php', $langconfig);
+ // Tests with a localised decimal separator.
+ $this->define_local_decimal_separator();
// Localisation on (default)
$this->assertEquals('5X43000', format_float(5.43, 5));
@@ -2160,6 +2173,80 @@ public function test_format_float() {
}
/**
+ * Test localised float unformatting.
+ */
+ public function test_unformat_float() {
+
+ // Tests without the localised decimal separator.
+
+ // Special case for null, empty or white spaces only strings.
+ $this->assertEquals(null, unformat_float(null));
+ $this->assertEquals(null, unformat_float(''));
+ $this->assertEquals(null, unformat_float(' '));
+
+ // Regular use.
+ $this->assertEquals(5.4, unformat_float('5.4'));
+ $this->assertEquals(5.4, unformat_float('5.4', true));
+
+ // No decimal.
+ $this->assertEquals(5.0, unformat_float('5'));
+
+ // Custom number of decimal.
+ $this->assertEquals(5.43267, unformat_float('5.43267'));
+
+ // Empty decimal.
+ $this->assertEquals(100.0, unformat_float('100.00'));
+
+ // With the thousand separator.
+ $this->assertEquals(1000.0, unformat_float('1 000'));
+ $this->assertEquals(1000.32, unformat_float('1 000.32'));
+
+ // Negative number.
+ $this->assertEquals(-100.0, unformat_float('-100'));
+
+ // Wrong value.
+ $this->assertEquals(0.0, unformat_float('Wrong value'));
+ // Wrong value in strict mode.
+ $this->assertFalse(unformat_float('Wrong value', true));
+
+ // Combining options.
+ $this->assertEquals(-1023.862567, unformat_float(' -1 023.862567 '));
+
+ // Bad decimal separator (should crop the decimal).
+ $this->assertEquals(50.0, unformat_float('50,57'));
+ // Bad decimal separator in strict mode (should return false).
+ $this->assertFalse(unformat_float('50,57', true));
+
+ // Tests with a localised decimal separator.
+ $this->define_local_decimal_separator();
+
+ // We repeat the tests above but with the current decimal separator.
+
+ // Regular use without and with the localised separator.
+ $this->assertEquals (5.4, unformat_float('5.4'));
+ $this->assertEquals (5.4, unformat_float('5X4'));
+
+ // Custom number of decimal.
+ $this->assertEquals (5.43267, unformat_float('5X43267'));
+
+ // Empty decimal.
+ $this->assertEquals (100.0, unformat_float('100X00'));
+
+ // With the thousand separator.
+ $this->assertEquals (1000.32, unformat_float('1 000X32'));
+
+ // Bad different separator (should crop the decimal).
+ $this->assertEquals (50.0, unformat_float('50Y57'));
+ // Bad different separator in strict mode (should return false).
+ $this->assertFalse (unformat_float('50Y57', true));
+
+ // Combining options.
+ $this->assertEquals (-1023.862567, unformat_float(' -1 023X862567 '));
+ // Combining options in strict mode.
+ $this->assertEquals (-1023.862567, unformat_float(' -1 023X862567 ', true));
+ }
+
+ /**
* Test deleting of users.
*/
public function test_delete_user() {
Please sign in to comment.
Something went wrong with that request. Please try again.