Completed
Push — master ( 4ee78f...ce1053 )
by Damian
14:52 queued 39s
created

NumericField::getSchemaValidation()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 0
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace SilverStripe\Forms;
4
5
use SilverStripe\ORM\DataObject;
6
use SilverStripe\i18n\i18n;
7
use Zend_Locale;
8
use Zend_Locale_Exception;
9
use Zend_Locale_Format;
10
11
/**
12
 * Text input field with validation for numeric values. Supports validating
13
 * the numeric value as to the {@link i18n::get_locale()} value, or an
14
 * overridden locale specific to this field.
15
 */
16
class NumericField extends TextField {
17
18
	protected $schemaDataType = FormField::SCHEMA_DATA_TYPE_DECIMAL;
19
20
	/**
21
	 * Override locale for this field.
22
	 *
23
	 * @var string
24
	 */
25
	protected $locale = null;
26
27
	/**
28
	 * @param mixed $value
29
	 * @param array $data
30
	 *
31
	 * @return $this
32
	 *
33
	 * @throws Zend_Locale_Exception
34
	 */
35
	public function setValue($value, $data = array()) {
36
		require_once "Zend/Locale/Format.php";
37
38
		// If passing in a non-string number, or a value
39
		// directly from a DataObject then localise this number
40
41
		if(is_int($value) || is_float($value) || $data instanceof DataObject) {
42
			$locale = new Zend_Locale($this->getLocale());
43
44
			$this->value = Zend_Locale_Format::toNumber(
45
				$value,
46
				array('locale' => $locale)
47
			);
48
		} else {
49
			$this->value = $this->clean($value);
50
		}
51
52
		return $this;
53
	}
54
55
	/**
56
	 * In some cases and locales, validation expects non-breaking spaces.
57
	 *
58
	 * Returns the value, with all spaces replaced with non-breaking spaces.
59
	 *
60
	 * @param string $input
61
	 *
62
	 * @return string
63
	 */
64
	protected function clean($input) {
65
		$replacement = html_entity_decode('&nbsp;', null, 'UTF-8');
66
67
		return str_replace(' ', $replacement, trim($input));
68
	}
69
70
	/**
71
	 * Determine if the current value is a valid number in the current locale.
72
	 *
73
	 * @return bool
74
	 */
75
	protected function isNumeric() {
76
		require_once "Zend/Locale/Format.php";
77
78
		$locale = new Zend_Locale($this->getLocale());
79
80
		return Zend_Locale_Format::isNumber(
81
			$this->clean($this->value),
82
			array('locale' => $locale)
83
		);
84
	}
85
86
	/**
87
	 * {@inheritdoc}
88
	 */
89
	public function Type() {
90
		return 'numeric text';
91
	}
92
93
	/**
94
	 * Validate this field
95
	 *
96
	 * @param Validator $validator
97
	 * @return bool
98
	 */
99
	public function validate($validator) {
100
		if(!$this->value) {
101
			return true;
102
		}
103
104
		if($this->isNumeric()) {
105
			return true;
106
		}
107
108
		$validator->validationError(
109
			$this->name,
110
			_t(
111
				'NumericField.VALIDATION',
112
				"'{value}' is not a number, only numbers can be accepted for this field",
113
				array('value' => $this->value)
114
			),
115
			"validation"
116
		);
117
118
		return false;
119
	}
120
121
	public function getSchemaValidation() {
122
		$rules = parent::getSchemaValidation();
123
		$rules['numeric'] = true;
124
		return $rules;
125
	}
126
127
	/**
128
	 * Extracts the number value from the localised string value.
129
	 *
130
	 * @return string
131
	 */
132
	public function dataValue() {
133
		require_once "Zend/Locale/Format.php";
134
135
		if(!$this->isNumeric()) {
136
			return 0;
137
		}
138
139
		$locale = new Zend_Locale($this->getLocale());
140
141
		$number = Zend_Locale_Format::getNumber(
142
			$this->clean($this->value),
143
			array('locale' => $locale)
144
		);
145
146
		return $number;
147
	}
148
149
	/**
150
	 * Creates a read-only version of the field.
151
	 *
152
	 * @return NumericField_Readonly
153
	 */
154
	public function performReadonlyTransformation() {
155
		$field = new NumericField_Readonly(
156
			$this->name,
157
			$this->title,
158
			$this->value
159
		);
160
161
		$field->setForm($this->form);
162
163
		return $field;
164
	}
165
166
	/**
167
	 * Gets the current locale this field is set to.
168
	 *
169
	 * @return string
170
	 */
171
	public function getLocale() {
172
		if($this->locale) {
173
			return $this->locale;
174
		}
175
176
		return i18n::get_locale();
177
	}
178
179
	/**
180
	 * Override the locale for this field.
181
	 *
182
	 * @param string $locale
183
	 *
184
	 * @return $this
185
	 */
186
	public function setLocale($locale) {
187
		$this->locale = $locale;
188
189
		return $this;
190
	}
191
}
192