MDL-24419 (3): Add new parameter to format_float for shorter display
authorsam marshall <s.marshall@open.ac.uk>
Thu, 26 Apr 2012 14:32:45 +0000 (15:32 +0100)
committersam marshall <s.marshall@open.ac.uk>
Mon, 14 May 2012 10:15:16 +0000 (11:15 +0100)
lib/moodlelib.php
lib/tests/moodlelib_test.php

index d781292..b621551 100644 (file)
@@ -9111,20 +9111,32 @@ function generate_password($maxlen=10) {
  * Given a float, prints it nicely.
  * Localized floats must not be used in calculations!
  *
+ * The stripzeros feature is intended for making numbers look nicer in small
+ * areas where it is not necessary to indicate the degree of accuracy by showing
+ * ending zeros. If you turn it on with $decimalpoints set to 3, for example,
+ * then it will display '5.4' instead of '5.400' or '5' instead of '5.000'.
+ *
  * @param float $float The float to print
  * @param int $decimalpoints The number of decimal places to print.
  * @param bool $localized use localized decimal separator
+ * @param bool $stripzeros If true, removes final zeros after decimal point
  * @return string locale float
  */
-function format_float($float, $decimalpoints=1, $localized=true) {
+function format_float($float, $decimalpoints=1, $localized=true, $stripzeros=false) {
     if (is_null($float)) {
         return '';
     }
     if ($localized) {
-        return number_format($float, $decimalpoints, get_string('decsep', 'langconfig'), '');
+        $separator = get_string('decsep', 'langconfig');
     } else {
-        return number_format($float, $decimalpoints, '.', '');
+        $separator = '.';
+    }
+    $result = number_format($float, $decimalpoints, $separator, '');
+    if ($stripzeros) {
+        // Remove zeros and final dot if not needed
+        $result = preg_replace('~(' . preg_quote($separator) . ')?0+$~', '', $result);
     }
+    return $result;
 }
 
 /**
index a67ebb7..6189919 100644 (file)
@@ -1818,4 +1818,45 @@ class moodlelib_testcase extends advanced_testcase {
         // used as a key
         $array = array(get_string('yes', null, null, true) => 'yes');
     }
+
+    /**
+     * Test localised float formatting.
+     */
+    public function test_format_float() {
+        global $SESSION, $CFG;
+
+        // Special case for null
+        $this->assertEquals('', format_float(null));
+
+        // Default 1 decimal place
+        $this->assertEquals('5.4', format_float(5.43));
+        $this->assertEquals('5.0', format_float(5.001));
+
+        // Custom number of decimal places
+        $this->assertEquals('5.43000', format_float(5.43, 5));
+
+        // Option to strip ending zeros after rounding
+        $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);
+
+        // Localisation on (default)
+        $this->assertEquals('5X43000', format_float(5.43, 5));
+        $this->assertEquals('5X43', format_float(5.43, 5, true, true));
+
+        // Localisation off
+        $this->assertEquals('5.43000', format_float(5.43, 5, false));
+        $this->assertEquals('5.43', format_float(5.43, 5, false, true));
+    }
 }