PluginProbe ʕ •ᴥ•ʔ
Pods – Custom Content Types and Fields / 2.7.31.4
Pods – Custom Content Types and Fields v2.7.31.4
2.7.31.4 2.8.23.5 2.9.19.5 3.0.10.5 3.1.4.3 3.2.8.4 3.3.9.2 2.8.23.4 2.9.19.4 3.0.10.4 3.1.4.2 3.2.8.3 3.3.9.1 trunk 1.14.8 2.7.31.3 2.8.23.3 2.9.19.3 3.0.10.3 3.1.4.1 3.2.0 3.2.1 3.2.1.1 3.2.2 3.2.4 3.2.5 3.2.6 3.2.7 3.2.7.1 3.2.8 3.2.8.1 3.2.8.2 3.3.0 3.3.1 3.3.2 3.3.3 3.3.4 3.3.5 3.3.6 3.3.7 3.3.8 3.3.9
pods / classes / fields / number.php
pods / classes / fields Last commit date
avatar.php 3 days ago boolean.php 3 days ago code.php 3 days ago color.php 3 days ago comment.php 3 days ago currency.php 3 days ago date.php 3 days ago datetime.php 3 days ago email.php 3 days ago file.php 3 days ago html.php 3 days ago link.php 3 days ago number.php 3 days ago oembed.php 3 days ago paragraph.php 3 days ago password.php 3 days ago phone.php 3 days ago pick.php 3 days ago slug.php 3 days ago taxonomy.php 3 days ago text.php 3 days ago time.php 3 days ago website.php 3 days ago wysiwyg.php 3 days ago
number.php
463 lines
1 <?php
2
3 /**
4 * @package Pods\Fields
5 */
6 class PodsField_Number extends PodsField {
7
8 /**
9 * {@inheritdoc}
10 */
11 public static $group = 'Number';
12
13 /**
14 * {@inheritdoc}
15 */
16 public static $type = 'number';
17
18 /**
19 * {@inheritdoc}
20 */
21 public static $label = 'Plain Number';
22
23 /**
24 * {@inheritdoc}
25 */
26 public static $prepare = '%d';
27
28 /**
29 * {@inheritdoc}
30 */
31 public function setup() {
32
33 self::$label = __( 'Plain Number', 'pods' );
34 }
35
36 /**
37 * {@inheritdoc}
38 */
39 public function options() {
40
41 $options = array(
42 static::$type . '_repeatable' => array(
43 'label' => __( 'Repeatable Field', 'pods' ),
44 'default' => 0,
45 'type' => 'boolean',
46 'help' => __( 'Making a field repeatable will add controls next to the field which allows users to Add/Remove/Reorder additional values. These values are saved in the database as an array, so searching and filtering by them may require further adjustments".', 'pods' ),
47 'boolean_yes_label' => '',
48 'dependency' => true,
49 'developer_mode' => true,
50 ),
51 static::$type . '_format_type' => array(
52 'label' => __( 'Input Type', 'pods' ),
53 'default' => 'number',
54 'type' => 'pick',
55 'data' => array(
56 'number' => __( 'Freeform Number', 'pods' ),
57 'slider' => __( 'Slider', 'pods' ),
58 ),
59 'dependency' => true,
60 ),
61 static::$type . '_format' => array(
62 'label' => __( 'Format', 'pods' ),
63 'default' => apply_filters( 'pods_form_ui_field_number_format_default', 'i18n' ),
64 'type' => 'pick',
65 'data' => array(
66 'i18n' => __( 'Localized Default', 'pods' ),
67 '9,999.99' => '1,234.00',
68 '9.999,99' => '1.234,00',
69 '9 999,99' => '1 234,00',
70 '9999.99' => '1234.00',
71 '9999,99' => '1234,00',
72 ),
73 ),
74 static::$type . '_decimals' => array(
75 'label' => __( 'Decimals', 'pods' ),
76 'default' => 0,
77 'type' => 'number',
78 'dependency' => true,
79 ),
80 static::$type . '_format_soft' => array(
81 'label' => __( 'Soft format?', 'pods' ),
82 'help' => __( 'Remove trailing decimals (0)', 'pods' ),
83 'default' => 0,
84 'type' => 'boolean',
85 'excludes-on' => array( static::$type . '_decimals' => 0 ),
86 ),
87 static::$type . '_step' => array(
88 'label' => __( 'Slider Increment (Step)', 'pods' ),
89 'depends-on' => array( static::$type . '_format_type' => 'slider' ),
90 'default' => 1,
91 'type' => 'text',
92 ),
93 static::$type . '_min' => array(
94 'label' => __( 'Minimum Number', 'pods' ),
95 'depends-on' => array( static::$type . '_format_type' => 'slider' ),
96 'default' => 0,
97 'type' => 'text',
98 ),
99 static::$type . '_max' => array(
100 'label' => __( 'Maximum Number', 'pods' ),
101 'depends-on' => array( static::$type . '_format_type' => 'slider' ),
102 'default' => 100,
103 'type' => 'text',
104 ),
105 static::$type . '_max_length' => array(
106 'label' => __( 'Maximum Length', 'pods' ),
107 'default' => 12,
108 'type' => 'number',
109 'help' => __( 'Set to -1 for no limit', 'pods' ),
110 ),
111 static::$type . '_placeholder' => array(
112 'label' => __( 'HTML Placeholder', 'pods' ),
113 'default' => '',
114 'type' => 'text',
115 'help' => array(
116 __( 'Placeholders can provide instructions or an example of the required data format for a field. Please note: It is not a replacement for labels or description text, and it is less accessible for people using screen readers.', 'pods' ),
117 'https://www.w3.org/WAI/tutorials/forms/instructions/#placeholder-text',
118 ),
119 ),
120 );
121
122 return $options;
123 }
124
125 /**
126 * {@inheritdoc}
127 */
128 public function schema( $options = null ) {
129
130 $length = (int) pods_v( static::$type . '_max_length', $options, 12, true );
131
132 if ( $length < 1 || 64 < $length ) {
133 $length = 64;
134 }
135
136 $decimals = $this->get_max_decimals( $options );
137
138 $schema = 'DECIMAL(' . $length . ',' . $decimals . ')';
139
140 return $schema;
141
142 }
143
144 /**
145 * {@inheritdoc}
146 */
147 public function prepare( $options = null ) {
148
149 $format = static::$prepare;
150
151 $decimals = $this->get_max_decimals( $options );
152
153 if( 6 < $decimals ) {
154 // %F only allows 6 decimals by default
155 $format = '%.' . $decimals . 'F';
156 } else if ( 0 < $decimals ) {
157 $format = '%F';
158 }
159
160 return $format;
161
162 }
163
164 /**
165 * @todo 2.8 Centralize the usage of this method. See PR #5540.
166 * {@inheritdoc}
167 */
168 public function is_empty( $value = null ) {
169
170 $is_empty = false;
171
172 $value = (float) $value;
173
174 if ( empty( $value ) ) {
175 $is_empty = true;
176 }
177
178 return $is_empty;
179
180 }
181
182 /**
183 * {@inheritdoc}
184 */
185 public function display( $value = null, $name = null, $options = null, $pod = null, $id = null ) {
186 return $this->format( $value, $name, $options, $pod, $id );
187 }
188
189 /**
190 * {@inheritdoc}
191 */
192 public function input( $name, $value = null, $options = null, $pod = null, $id = null ) {
193
194 $options = (array) $options;
195 $form_field_type = PodsForm::$field_type;
196 $is_read_only = false;
197
198 if ( is_array( $value ) ) {
199 $value = implode( '', $value );
200 }
201
202 if ( 'slider' === pods_v( static::$type . '_format_type', $options, 'number' ) ) {
203 $field_type = 'slider';
204 } else {
205 $field_type = static::$type;
206 }
207
208 if ( isset( $options['name'] ) && false === PodsForm::permission( static::$type, $options['name'], $options, null, $pod, $id ) ) {
209 if ( pods_v( 'read_only', $options, false ) ) {
210 $is_read_only = true;
211 } else {
212 return;
213 }
214 } elseif ( ! pods_has_permissions( $options ) && pods_v( 'read_only', $options, false ) ) {
215 $is_read_only = true;
216 }
217
218 if ( $is_read_only ) {
219 $options['readonly'] = true;
220
221 $field_type = 'text';
222
223 $value = $this->format( $value, $name, $options, $pod, $id );
224 }
225
226 pods_view( PODS_DIR . 'ui/fields/' . $field_type . '.php', compact( array_keys( get_defined_vars() ) ) );
227
228 }
229
230 /**
231 * {@inheritdoc}
232 */
233 public function regex( $value = null, $name = null, $options = null, $pod = null, $id = null ) {
234
235 $format_args = $this->get_number_format_args( $options );
236 $thousands = $format_args['thousands'];
237 $dot = $format_args['dot'];
238
239 return '\-*[0-9\\' . implode( '\\', array_filter( array( $dot, $thousands ) ) ) . ']+';
240 }
241
242 /**
243 * {@inheritdoc}
244 */
245 public function validate( $value, $name = null, $options = null, $fields = null, $pod = null, $id = null, $params = null ) {
246 $validate = parent::validate( $value, $name, $options, $fields, $pod, $id, $params );
247
248 $errors = array();
249
250 if ( is_array( $validate ) ) {
251 $errors = $validate;
252 }
253
254 $format_args = $this->get_number_format_args( $options );
255 $thousands = $format_args['thousands'];
256 $dot = $format_args['dot'];
257
258 $check = str_replace(
259 array( $thousands, $dot, html_entity_decode( $thousands ) ),
260 array( '', '.', '' ),
261 $value
262 );
263 $check = trim( $check );
264
265 $check = preg_replace( '/[0-9\.\-\s]/', '', $check );
266
267 $label = pods_v( 'label', $options, ucwords( str_replace( '_', ' ', $name ) ) );
268
269 if ( 0 < strlen( $check ) ) {
270 // Translators: %s stands for the input value.
271 $errors[] = sprintf( esc_html__( '%s is not numeric', 'pods' ), $label );
272 }
273
274 if ( ! empty( $errors ) ) {
275 return $errors;
276 }
277
278 return $validate;
279 }
280
281 /**
282 * {@inheritdoc}
283 */
284 public function pre_save( $value, $id = null, $name = null, $options = null, $fields = null, $pod = null, $params = null ) {
285
286 $format_args = $this->get_number_format_args( $options );
287 $thousands = $format_args['thousands'];
288 $dot = $format_args['dot'];
289 $decimals = $format_args['decimals'];
290
291 if ( 'slider' !== pods_v( static::$type . '_format_type', $options ) ) {
292 // Slider only supports `1234.00` format so no need for replacing characters.
293 $value = str_replace(
294 array( $thousands, html_entity_decode( $thousands ), $dot, html_entity_decode( $dot ) ),
295 array( '', '', '.', '.' ),
296 $value
297 );
298 }
299
300 $value = trim( $value );
301
302 $value = preg_replace( '/[^0-9\.\-]/', '', $value );
303
304 if ( $this->is_empty( $value ) && ( ! is_numeric( $value ) || 0.0 !== (float) $value ) ) {
305 // Don't enforce a default value here.
306 return null;
307 }
308
309 $value = number_format( (float) $value, $decimals, '.', '' );
310
311 // Optionally remove trailing decimal zero's.
312 if ( pods_v( static::$type . '_format_soft', $options, false ) ) {
313 $value = $this->trim_decimals( $value, '.' );
314 }
315
316 return $value;
317 }
318
319 /**
320 * {@inheritdoc}
321 */
322 public function format( $value = null, $name = null, $options = null, $pod = null, $id = null ) {
323
324 if ( $this->is_empty( $value ) && ( ! is_numeric( $value ) || 0.0 !== (float) $value ) ) {
325 // Don't enforce a default value here.
326 return null;
327 }
328
329 $format_args = $this->get_number_format_args( $options );
330 $thousands = $format_args['thousands'];
331 $dot = $format_args['dot'];
332 $decimals = $format_args['decimals'];
333
334 if ( 'i18n' === pods_v( static::$type . '_format', $options ) ) {
335 $value = number_format_i18n( (float) $value, $decimals );
336 } else {
337 $value = number_format( (float) $value, $decimals, $dot, $thousands );
338 }
339
340 // Optionally remove trailing decimal zero's.
341 if ( pods_v( static::$type . '_format_soft', $options, false ) ) {
342 $value = $this->trim_decimals( $value, $dot );
343 }
344
345 return $value;
346 }
347
348 /**
349 * Trim trailing 0 decimals from numbers.
350 *
351 * @since 2.7.15
352 *
353 * @param string $value
354 * @param string $dot
355 *
356 * @return string
357 */
358 public function trim_decimals( $value, $dot ) {
359 $parts = explode( $dot, $value );
360
361 if ( isset( $parts[1] ) ) {
362 $parts[1] = rtrim( $parts[1], '0' );
363
364 if ( empty( $parts[1] ) ) {
365 unset( $parts[1] );
366 }
367 }
368
369 return implode( $dot, $parts );
370 }
371
372 /**
373 * Get the formatting arguments for numbers.
374 *
375 * @since 2.7.0
376 *
377 * @param array $options Field options.
378 *
379 * @return array {
380 * @type string $thousands
381 * @type string $dot
382 * @type int $decimals
383 * }
384 */
385 public function get_number_format_args( $options ) {
386
387 $format = pods_v( static::$type . '_format', $options );
388 $format = pods_unslash( $format );
389
390 switch ( $format ) {
391 case '9.999,99':
392 $thousands = '.';
393 $dot = ',';
394 break;
395 case '9,999.99':
396 $thousands = ',';
397 $dot = '.';
398 break;
399 case '9\'999.99':
400 $thousands = '\'';
401 $dot = '.';
402 break;
403 case '9 999,99':
404 $thousands = ' ';
405 $dot = ',';
406 break;
407 case '9999.99':
408 $thousands = '';
409 $dot = '.';
410 break;
411 case '9999,99':
412 $thousands = '';
413 $dot = ',';
414 break;
415 default:
416 global $wp_locale;
417 $thousands = $wp_locale->number_format['thousands_sep'];
418 $dot = $wp_locale->number_format['decimal_point'];
419 break;
420 }
421
422 $decimals = $this->get_max_decimals( $options );
423
424 return array(
425 'thousands' => $thousands,
426 'dot' => $dot,
427 'decimals' => $decimals,
428 );
429 }
430
431 /**
432 * Get the max allowed decimals.
433 *
434 * @since 2.7.0
435 *
436 * @param array $options Field options.
437 *
438 * @return int
439 */
440 public function get_max_decimals( $options ) {
441
442 $length = (int) pods_v( static::$type . '_max_length', $options, 12, true );
443
444 if ( $length < 1 || 64 < $length ) {
445 $length = 64;
446 }
447
448 $decimals = (int) pods_v( static::$type . '_decimals', $options, 0 );
449
450 if ( $decimals < 1 ) {
451 $decimals = 0;
452 } elseif ( 30 < $decimals ) {
453 $decimals = 30;
454 }
455
456 if ( $length < $decimals ) {
457 $decimals = $length;
458 }
459
460 return $decimals;
461 }
462 }
463