weekly release 4.5dev
[moodle.git] / lib / form / float.php
blobe1685f207de467544a45cc5136ee3814f7acf219
1 <?php
2 // This file is part of Moodle - http://moodle.org/
3 //
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
18 /**
19 * Float type form element
21 * Contains HTML class for a float type element
23 * @package core_form
24 * @category form
25 * @copyright 2019 Shamim Rezaie <shamim@moodle.com>
26 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
29 defined('MOODLE_INTERNAL') || die();
31 global $CFG;
32 require_once($CFG->libdir . '/form/text.php');
34 /**
35 * Float type form element.
37 * This is preferred over the text element when working with float numbers, and takes care of the fact that different languages
38 * may use different symbols as the decimal separator.
39 * Using this element, submitted float numbers will be automatically translated from the localised format into the computer format,
40 * and vice versa when they are being displayed.
42 * @copyright 2019 Shamim Rezaie <shamim@moodle.com>
43 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
45 class MoodleQuickForm_float extends MoodleQuickForm_text {
47 /**
48 * MoodleQuickForm_float constructor.
50 * @param string $elementName (optional) name of the float field
51 * @param string $elementLabel (optional) float field label
52 * @param string $attributes (optional) Either a typical HTML attribute string or an associative array
54 public function __construct($elementName = null, $elementLabel = null, $attributes = null) {
55 parent::__construct($elementName, $elementLabel, $attributes);
56 $this->_type = 'float';
59 /**
60 * Called by HTML_QuickForm whenever form event is made on this element.
62 * @param string $event Name of event
63 * @param mixed $arg event arguments
64 * @param object $caller calling object
65 * @return bool
67 public function onQuickFormEvent($event, $arg, &$caller) {
68 switch ($event) {
69 case 'updateValue':
70 if ($value = $this->_findValue($caller->_constantValues)) {
71 $value = $this->format_float($value);
73 if (null === $value) {
74 $value = $this->_findValue($caller->_submitValues);
75 if (null === $value) {
76 if ($value = $this->_findValue($caller->_defaultValues)) {
77 $value = $this->format_float($value);
81 if (null !== $value) {
82 parent::setValue($value);
84 return true;
85 case 'createElement':
86 $caller->setType($arg[0], PARAM_RAW_TRIMMED);
87 default:
88 return parent::onQuickFormEvent($event, $arg, $caller);
92 /**
93 * Checks that the submitted value is a valid float number.
95 * @param string $value The localised float number that is submitted.
96 * @return string|null Validation error message or null.
98 public function validateSubmitValue($value) {
99 if (false === unformat_float($value, true)) {
100 return get_string('err_numeric', 'core_form');
105 * Sets the value of the form element.
107 * @param string $value Default value of the form element
109 public function setValue($value) {
110 $value = $this->format_float($value);
111 parent::setValue($value);
115 * Returns the value of the form element.
117 * @return false|float
119 public function getValue() {
120 $value = parent::getValue();
121 if ($value) {
122 $value = unformat_float($value, true);
124 return $value;
128 * Returns a 'safe' element's value.
130 * @param array $submitValues array of submitted values to search
131 * @param bool $assoc whether to return the value as associative array
132 * @return mixed
134 public function exportValue(&$submitValues, $assoc = false) {
135 $value = $this->_findValue($submitValues);
136 if (null === $value) {
137 $value = $this->getValue();
138 } else if ($value) {
139 $value = unformat_float($value, true);
141 return $this->_prepareValue($value, $assoc);
145 * Used by getFrozenHtml() to pass the element's value if _persistantFreeze is on.
147 * @return string
149 public function _getPersistantData() {
150 if (!$this->_persistantFreeze) {
151 return '';
152 } else {
153 $id = $this->getAttribute('id');
154 if (isset($id)) {
155 // Id of persistant input is different then the actual input.
156 $id = array('id' => $id . '_persistant');
157 } else {
158 $id = array();
161 return '<input' . $this->_getAttrString(array(
162 'type' => 'hidden',
163 'name' => $this->getAttribute('name'),
164 'value' => $this->getAttribute('value')
165 ) + $id) . ' />';
170 * Given a float, prints it nicely.
171 * This function reserves the number of decimal places.
173 * @param float|null $value The float number to format
174 * @return string Localised float
176 private function format_float($value) {
177 if (is_numeric($value)) {
178 // We want to keep trailing zeros after the decimal point if there is any.
179 // Therefore we cannot just call format_float() and pass -1 as the number of decimal points.
180 $pieces = preg_split('/E/i', $value); // In case it is in the scientific format.
181 $decimalpos = strpos($pieces[0], '.');
182 if ($decimalpos !== false) {
183 $decimalpart = substr($pieces[0], $decimalpos + 1);
184 $decimals = strlen($decimalpart);
185 } else {
186 $decimals = 0;
188 $pieces[0] = format_float($pieces[0], $decimals);
189 $value = implode('E', $pieces);
191 return $value;