1
0
mirror of https://github.com/processwire/processwire.git synced 2025-08-14 10:45:54 +02:00

Refactoring, minor improvements and phpdoc additions to FieldtypeInteger, FieldtypeFloat, InputfieldInteger, InputfieldFloat. No new features added, just code improvements.

This commit is contained in:
Ryan Cramer
2020-08-20 07:38:39 -04:00
parent 0b9f07f3c4
commit 2b69123f59
4 changed files with 480 additions and 222 deletions

View File

@@ -8,7 +8,7 @@
* For documentation about the fields used in this class, please see:
* /wire/core/Fieldtype.php
*
* ProcessWire 3.x, Copyright 2016 by Ryan Cramer
* ProcessWire 3.x, Copyright 2020 by Ryan Cramer
* https://processwire.com
*
*/
@@ -19,90 +19,118 @@ class FieldtypeFloat extends Fieldtype {
return array(
'title' => __('Float', __FILE__),
'summary' => __('Field that stores a floating point (decimal) number', __FILE__),
'version' => 105,
'version' => 106,
'permanent' => true,
);
);
}
/**
* Get compatible Fieldtypes
*
* @param Field $field
* @return null|Fieldtypes
*
*/
public function ___getCompatibleFieldtypes(Field $field) {
$fieldtypes = parent::___getCompatibleFieldtypes($field);
foreach($fieldtypes as $type) {
if( !$type instanceof FieldtypeInteger &&
!$type instanceof FieldtypeFloat &&
$type != 'FieldtypeText') {
if(!$type instanceof FieldtypeInteger && !$type instanceof FieldtypeFloat && $type != 'FieldtypeText') {
$fieldtypes->remove($type);
}
}
return $fieldtypes;
}
/**
* Get blank value
*
* @param Page $page
* @param Field $field
* @return string
*
*/
public function getBlankValue(Page $page, Field $field) {
return '';
}
/**
* Is given value considered empty to this Fieldtype?
*
* @param Field $field
* @param mixed $value
* @return bool
*
*/
public function isEmptyValue(Field $field, $value) {
if(($value === "0" || $value === 0 || $value === "0.0" || $value === 0.0) && $field->zeroNotEmpty) {
if($value === "0" || $value === 0 || $value === "0.0" || $value === 0.0) {
// when zeroNotEmpty option is set, we don't count a literal "0" is being a blank value
return false;
if($field->get('zeroNotEmpty')) return false;
}
return empty($value);
}
/**
* Sanitize value
*
* @param Page $page
* @param Field $field
* @param float|int|string $value
* @return float|string
*
*/
public function sanitizeValue(Page $page, Field $field, $value) {
if(!strlen("$value")) return '';
if(!is_float($value) && !is_int($value)) {
$value = $this->wire('sanitizer')->float((string) $value, array('blankValue' => ''));
$value = $this->wire()->sanitizer->float((string) $value, array('blankValue' => ''));
}
if(is_null($field->precision)) {
$precision = $field->get('precision');
if($precision === null || $precision === '') {
$value = (float) $value;
} else {
$value = round((float) $value, $field->precision);
$value = round((float) $value, $precision);
}
return $value;
}
/*
public function formatValue(Page $page, Field $field, $value) {
// @todo add support for number_format options
return $value;
}
*/
/**
* Get Inputfield for this Fieldtype
*
* @param Page $page
* @param Field $field
* @return Inputfield
*
*/
public function getInputfield(Page $page, Field $field) {
$inputfield = $this->modules->get('InputfieldFloat');
$inputfield->class = $this->className();
$inputfield->precision = $field->precision;
/** @var InputfieldFloat $inputfield */
$inputfield = $this->wire()->modules->get('InputfieldFloat');
$inputfield->addClass($this->className());
$inputfield->precision = $field->get('precision');
return $inputfield;
}
/**
* Sleep value for DB storage
*
* @param Page $page
* @param Field $field
* @param string|float|int
* @return string
*
*/
public function ___sleepValue(Page $page, Field $field, $value) {
$precision = $field->precision;
if(is_null($precision)) $precision = self::getPrecision($value);
$precision = $field->get('precision');
if(is_null($precision) || $precision === '') $precision = self::getPrecision($value);
if(!is_string($value)) $value = number_format($value, $precision, '.', '');
/*
// handle commas vs. dots issue with other locales
$info = localeconv();
if(!empty($info['mon_thousands_sep'])) {
if(strpos($value, $info["mon_thousands_sep"]) !== false) {
$value = str_replace($info["mon_thousands_sep"] , "", $value);
}
}
if(!empty($info['mon_decimal_point'])) {
if($info["mon_decimal_point"] !== '.' && strpos($value, $info["mon_decimal_point"]) !== false) {
$value = str_replace($info["mon_decimal_point"] , ".", $value);
}
}
$value = floatval($value);
*/
return $value;
}
/**
* Get precision of given value
*
* @param string|float $value
* @return int
*
*/
public static function getPrecision($value) {
$value = (float) $value;
$remainder = ceil($value) - $value;
@@ -111,31 +139,67 @@ class FieldtypeFloat extends Fieldtype {
return $precision;
}
/**
* Get DB schema for this Fieldtype
*
* @param Field $field
* @return array
*
*/
public function getDatabaseSchema(Field $field) {
$schema = parent::getDatabaseSchema($field);
$schema['data'] = 'float NOT NULL';
return $schema;
}
/**
* Get field configuration
*
* @param Field $field
* @return InputfieldWrapper
*
*/
public function ___getConfigInputfields(Field $field) {
$inputfields = parent::___getConfigInputfields($field);
if(is_null($field->precision)) $field->precision = 2;
$precision = $field->get('precision');
if($precision === null) $precision = 2;
/** @var InputfieldInteger $f */
$f = $this->modules->get('InputfieldInteger');
$f = $this->wire()->modules->get('InputfieldInteger');
$f->attr('name', 'precision');
$f->label = $this->_('Number of decimal digits to round to');
$f->attr('value', $field->precision);
if($precision !== '') $f->val($precision);
$f->attr('size', 8);
$inputfields->append($f);
$f = $this->wire('modules')->get('FieldtypeInteger')->___getConfigInputfields($field)->getChildByName('zeroNotEmpty');
/** @var FieldtypeInteger $ft */
$ft = $this->wire()->modules->get('FieldtypeInteger');
// use the same 'zeroNotEmpty' setting as FieldtypeInteger
$f = $ft->___getConfigInputfields($field)->getChildByName('zeroNotEmpty');
if($f) $inputfields->add($f);
return $inputfields;
}
/**
* Convert float string with commas to float value
*
* @param string $str
* @return float|string
* @deprecated Use $sanitizer->float($value, [ 'blankValue' = '' ]) instead
*
*/
public static function strToFloat($str) {
return wire('sanitizer')->float($str, array('blankValue' => ''));
}
/*
public function formatValue(Page $page, Field $field, $value) {
// @todo add support for number_format options
return $value;
}
*/
/*
public function getMatchQuery($query, $table, $subfield, $operator, $value) {
if(!is_int($value) && !is_float($value)) {
@@ -145,19 +209,6 @@ class FieldtypeFloat extends Fieldtype {
}
*/
/**
* Convert float string with commas to float value
*
* Most based on: http://php.net/manual/en/function.floatval.php#114486
*
* @param string $str
* @return float|string
* @deprecated
*
*/
public static function strToFloat($str) {
return wire('sanitizer')->float($str, array('blankValue' => ''));
}
}

View File

@@ -8,7 +8,7 @@
* For documentation about the fields used in this class, please see:
* /wire/core/Fieldtype.php
*
* ProcessWire 3.x, Copyright 2016 by Ryan Cramer
* ProcessWire 3.x, Copyright 2020 by Ryan Cramer
* https://processwire.com
*
* @todo allow for more integer types (tiny, small, medium, big) and unsigned option
@@ -20,25 +20,37 @@ class FieldtypeInteger extends Fieldtype {
public static function getModuleInfo() {
return array(
'title' => 'Integer',
'version' => 101,
'version' => 102,
'summary' => 'Field that stores an integer',
'permanent' => true,
);
);
}
/**
* Get compatible Fieldtypes
*
* @param Field $field
* @return Fieldtypes
*
*/
public function ___getCompatibleFieldtypes(Field $field) {
$fieldtypes = parent::___getCompatibleFieldtypes($field);
foreach($fieldtypes as $type) {
if( !$type instanceof FieldtypeInteger &&
!$type instanceof FieldtypeFloat &&
$type != 'FieldtypeText') {
if(!$type instanceof FieldtypeInteger && !$type instanceof FieldtypeFloat && $type != 'FieldtypeText') {
$fieldtypes->remove($type);
}
}
return $fieldtypes;
}
/**
* Is given value considered empty by this Fieldtype?
*
* @param Field $field
* @param mixed $value
* @return bool
*
*/
public function isEmptyValue(Field $field, $value) {
if(($value === "0" || $value === 0) && $field->get('zeroNotEmpty')) {
// when zeroNotEmpty option is set, we don't count a literal "0" is being a blank value
@@ -46,90 +58,154 @@ class FieldtypeInteger extends Fieldtype {
}
return empty($value);
}
/**
* Is value one that should be deleted rather than stored in the DB?
*
* @param Page $page
* @param Field $field
* @param mixed $value
* @return bool
*
*/
public function isDeleteValue(Page $page, Field $field, $value) {
return $this->isEmptyValue($field, $value);
}
/**
* Get the blank value for this Fieldtype
*
* @param Page $page
* @param Field $field
* @return string
*
*/
public function getBlankValue(Page $page, Field $field) {
return '';
}
/**
* Sanitize value to integer or blank string (for no value)
*
* @param Page $page
* @param Field $field
* @param int|string|mixed $value
* @return int|string
*
*/
public function sanitizeValue(Page $page, Field $field, $value) {
if(is_string($value) && strlen($value) && !ctype_digit(ltrim($value, '-'))) {
// string value with one or more non-digit characters
$value = trim($value);
// trim off common currency symbols
$value = trim($value, '$€ ');
if(ctype_digit("$value")) {
// trimming reduced it to an int
} else if(preg_match('/^(\de\d|0x\d+|\+\d+)/', $value)) {
// likely a valid number, but in a non-native format to PW
// examples: 1e123213, 0x1234, +123 (intval handles these)
$value = intval($value);
} else if(preg_match('/^[^-+\d.]+/', $value)) {
// string starting with something we don't recognize, let PHP decide
// example: bd#79
$value = intval($value);
if($value === 0) $value = ''; // blank rather than zero
} else {
// string value that looks like a number but has some other stuff in it
// see if there are some definitely non-number chars in there, and truncate
// the string to that point if we find any
if(preg_match('/^(-?[\d,. ]+)([^\d,. ]+)/', $value, $matches)) {
$value = $matches[1];
}
// check to see if we're dealing with a potential float val or thousands separators
if(strpos($value, '.') !== false || strpos($value, ',') !== false || strpos($value, ' ') !== false) {
// convert float values to rounded integers
// also handles values with thousands separators
$value = round(FieldtypeFloat::strToFloat($value));
} else if(is_numeric($value)) {
// let PHP decide how to convert it
$value = intval($value);
} else {
// default: replace non numeric characters
$negative = substr(trim($value), 0, 1) == '-';
$value = preg_replace('/[^\d]/', '', $value);
$value = strlen($value) ? (int) $value : '';
if($negative && is_int($value)) $value = $value * -1;
}
}
$value = $this->sanitizeValueString($value);
} else {
$value = strlen("$value") ? (int) $value : '';
}
$value = strlen("$value") ? (int) $value : '';
return $value;
}
/**
* Sanitize string to integer or blank string if empty
*
* @param string $value
* @return int|string
*
*/
protected function sanitizeValueString($value) {
// string value with one or more non-digit characters
$value = trim($value);
// trim off common currency symbols
$value = trim($value, '$€ ');
if(ctype_digit("$value")) {
// trimming reduced it to an int
} else if(preg_match('/^(\de\d|0x\d+|\+\d+)/', $value)) {
// likely a valid number, but in a non-native format to PW
// examples: 1e123213, 0x1234, +123 (intval handles these)
$value = intval($value);
} else if(preg_match('/^[^-+\d.]+/', $value)) {
// string starting with something we don't recognize, let PHP decide
// example: bd#79
$value = intval($value);
if($value === 0) $value = ''; // blank rather than zero
} else {
// string value that looks like a number but has some other stuff in it
// see if there are some definitely non-number chars in there, and truncate
// the string to that point if we find any
if(preg_match('/^(-?[\d,. ]+)([^\d,. ]+)/', $value, $matches)) {
$value = $matches[1];
}
// check to see if we're dealing with a potential float val or thousands separators
if(strpos($value, '.') !== false || strpos($value, ',') !== false || strpos($value, ' ') !== false) {
// convert float values to rounded integers
// also handles values with thousands separators
$value = $this->wire()->sanitizer->float($value, array('blankValue' => ''));
if($value !== '') $value = round($value);
} else if(is_numeric($value)) {
// let PHP decide how to convert it
$value = intval($value);
} else {
// default: replace non numeric characters
$negative = substr(trim($value), 0, 1) == '-';
$value = preg_replace('/[^\d]/', '', $value);
$value = strlen($value) ? (int) $value : '';
if($negative && is_int($value)) $value = $value * -1;
}
}
return strlen("$value") ? (int) $value : '';
}
/**
* Get Inputfield for this Fieldtype
*
* @param Page $page
* @param Field $field
* @return Inputfield|InputfieldInteger
*
*/
public function getInputfield(Page $page, Field $field) {
/** @var InputfieldInteger $inputfield */
$inputfield = $this->modules->get('InputfieldInteger');
$inputfield->class = $this->className();
$inputfield = $this->wire()->modules->get('InputfieldInteger');
$inputfield->addClass($this->className());
return $inputfield;
}
/**
* Get DB schema
*
* @param Field $field
* @return array
*
*/
public function getDatabaseSchema(Field $field) {
$schema = parent::getDatabaseSchema($field);
$schema['data'] = 'int NOT NULL';
return $schema;
}
/**
* Get Inputfields to configure integer field
*
* @param Field $field
* @return InputfieldWrapper
*
*/
public function ___getConfigInputfields(Field $field) {
$inputfields = parent::___getConfigInputfields($field);
/** @var InputfieldRadios $f */
$f = $this->wire('modules')->get('InputfieldRadios');
$f = $this->wire()->modules->get('InputfieldRadios');
$f->label = $this->_('Are blank and 0 equivalent?');
$f->description = $this->_('This affects how ProcessWire matches pages during database find operations.') . ' ' .
$this->_('If 0 and blank are equivalent (the Yes option) then a search for **field=0** or **field=""** will produce the same results.') . ' ' .
@@ -142,7 +218,7 @@ class FieldtypeInteger extends Fieldtype {
$inputfields->add($f);
/** @var InputfieldInteger $f */
$f = $this->wire('modules')->get('InputfieldInteger');
$f = $this->wire()->modules->get('InputfieldInteger');
$f->attr('name', 'defaultValue');
$f->label = $this->_('Default value');
$f->description = $this->_('This value is assigned as the default for this field on newly created pages. It does not affect existing pages.');

View File

@@ -2,8 +2,19 @@
/**
* Inputfield for floating point numbers
*
* ProcessWire 3.x, Copyright 2020 by Ryan Cramer
* https://processwire.com
*
* @property int $precision
* @property string $inputType Input type to use, one of "text" or "number"
* @property int|float $min
* @property int|float $max
* @property int|float|string $step
* @property int $size
* @property string $placeholder
* @property int|float $initValue Initial/default value (when used as independent Inputfield)
* @property int|float|string $defaultValue Initial/default value (when used with FieldtypeInteger)
*
*/
@@ -13,76 +24,130 @@ class InputfieldFloat extends InputfieldInteger {
return array(
'title' => __('Float', __FILE__), // Module Title
'summary' => __('Floating point number with precision', __FILE__), // Module Summary
'version' => 103,
'version' => 104,
'permanent' => true,
);
);
}
/**
* Construct
*
*/
public function __construct() {
$this->set('precision', 2);
parent::__construct();
}
/**
* Module init
*
*/
public function init() {
parent::init();
$this->attr('step', 'any'); // HTML5 attr required to support decimals with 'number' types
}
protected function sanitizeValue($value) {
if(!is_float($value) && !is_int($value)) {
$value = FieldtypeFloat::strToFloat((string) $value);
}
$precision = $this->precision;
if(is_null($precision)) $precision = FieldtypeFloat::getPrecision($value);
return strlen("$value") ? round((float) $value, $precision) : '';
/**
* Get configured precision setting, or if given a value, precision of the value
*
* @param float|string|null $value
* @return int|string Returns integer of precision or blank string if none defined
*
*/
protected function getPrecision($value = null) {
if($value !== null) return FieldtypeFloat::getPrecision($value);
$precision = $this->precision;
return $precision === null || $precision === '' ? '' : (int) $precision;
}
/**
* Returns true if number is in valid range, false if not
*
* Overriding the function from InputfieldInteger to ensure float types (rather than int types) are used
* Sanitize value
*
* @param float $value
* @return bool
* @param float|string $value
* @return float|string
*
*/
protected function sanitizeValue($value) {
if(!strlen("$value")) return '';
if(!is_float($value) && !is_int($value)) {
$value = $this->wire()->sanitizer->float($value, array('blankValue' => ''));
if(!strlen("$value")) return '';
}
$precision = $this->precision;
if($precision === null || $precision === '') {
$precision = FieldtypeFloat::getPrecision($value);
}
return round((float) $value, $precision);
}
/**
* Typecast value to float, override from InputfieldInteger
*
* @param string|int|float $value
* @return int
*
*/
protected function isInRange($value) {
$inRange = true;
$min = $this->attr('min');
$max = $this->attr('max');
if(strlen("$value")) {
if(strlen("$min") && ((float) $value) < ((float) $min)) {
$inRange = false;
}
if(strlen("$max") && ((float) $value) > ((float) $max)) {
$inRange = false;
}
}
return $inRange;
protected function typeValue($value) {
return (float) $value;
}
/**
* Override method from Inputfield to properly handle HTML5 number values
* Override method from Inputfield to convert local specific decimals for input[type=number]
*
* @param array $attributes
* @return string
*
*/
public function getAttributesString(array $attributes = null) {
if($attributes && $attributes['type'] === 'number' && is_float($attributes['value'])) {
if(strlen("$attributes[value]") && !ctype_digit(str_replace('.', '', $attributes['value']))) {
if($attributes && $attributes['type'] === 'number') {
$value = isset($attributes['value']) ? $attributes['value'] : null;
if(is_float($value) && strlen("$value") && !ctype_digit(str_replace('.', '', $value))) {
// float value is using a non "." as decimal point, needs conversion because
// the HTML5 number input type requires "." as the decimal
$locale = localeconv();
$decimal = $locale['decimal_point'];
if($decimal !== '.' && strpos("$attributes[value]", $decimal) !== false) {
$parts = explode($decimal, $attributes['value'], 2);
if(count($parts) == 2) {
$attributes['value'] = implode('.', $parts);
}
}
$attributes['value'] = $this->localeConvertValue($value);
}
}
return parent::getAttributesString($attributes);
}
/**
* Convert floats with non "." decimal points to use "." decimal point according to locale
*
* @param float|string $value
* @return string|float Returns string representation of float when value was converted
*
*/
protected function localeConvertValue($value) {
if(!strlen("$value")) return $value;
if(ctype_digit(str_replace('.', '', $value))) return $value;
$locale = localeconv();
$decimal = $locale['decimal_point'];
if($decimal === '.' || strpos($value, $decimal) === false) return $value;
$parts = explode($decimal, $value, 2);
$value = implode('.', $parts);
return $value;
}
/**
* Inputfield config
*
* @return InputfieldWrapper
*
*/
public function getConfigInputfields() {
$inputfields = parent::getConfigInputfields();
if($this->hasFieldtype === false) {
/** @var InputfieldInteger $f */
$f = $this->wire()->modules->get('InputfieldInteger');
$f->attr('name', 'precision');
$f->label = $this->_('Number of decimal digits to round to');
$f->attr('value', $this->precision);
$f->attr('size', 8);
$inputfields->add($f);
} else {
// precision is configured with FieldtypeFloat
}
return $inputfields;
}
}

View File

@@ -1,13 +1,19 @@
<?php namespace ProcessWire;
/**
* Class InputfieldInteger
* Integer Inputfield
*
* @property string $inputType
* @property int|float $initValue
* ProcessWire 3.x, Copyright 2020 by Ryan Cramer
* https://processwire.com
*
* @property string $inputType Input type to use, one of "text" or "number"
* @property int|float $min
* @property int|float $max
* @property int|float|string $step
* @property int $size
* @property string $placeholder
* @property int|float $initValue Initial/default value (when used as independent Inputfield)
* @property int|float|string $defaultValue Initial/default value (when used with FieldtypeInteger)
*
*/
@@ -17,48 +23,57 @@ class InputfieldInteger extends Inputfield {
return array(
'title' => __('Integer', __FILE__), // Module Title
'summary' => __('Integer (positive or negative)', __FILE__), // Module Summary
'version' => 104,
'version' => 105,
'permanent' => true,
);
);
}
/**
* Module init
*
*/
public function init() {
parent::init();
$this->set('inputType', 'text');
$this->attr('type', 'text');
$this->attr('min', ''); // blank means not set
$this->attr('max', ''); // blank means not set
$this->attr('min', '');
$this->attr('max', '');
$this->attr('step', '');
$this->attr('size', '10');
$this->attr('placeholder', '');
$this->set('inputType', 'text');
$this->set('initValue', '');
$this->set('defaultValue', '');
}
/**
* Render Inputfield
*
* @return string
*
*/
public function ___render() {
if(!$this->attr('type')) $this->attr('type', 'text');
$attrs = $this->getAttributes();
$note = '';
if(empty($attrs['size'])) {
$attrs['class'] = (isset($attrs['class']) ? "$attrs[class] " : "") . 'InputfieldMaxWidth';
unset($attrs['size']);
}
if(!strlen("$attrs[min]") && !strlen("$attrs[max]")) {
// if both min+max are empty, then consider them non-applicable
unset($attrs['min'], $attrs['max']);
if($attrs['type'] === 'text') {
// input[type=text] unset attributes not applicable
unset($attrs['step'], $attrs['min'], $attrs['max']);
} else {
// unset any that aren't applicable
if(strlen("$attrs[min]")) $note .= sprintf($this->_('Min: %d'), $attrs['min']);
else unset($attrs['min']);
if(strlen("$attrs[max]")) $note .= ($note ? ', ' : '') . sprintf($this->_('Max: %d'), $attrs['max']);
else unset($attrs['max']);
// input[type=number] unset any that aren't applicable
foreach(array('min', 'max', 'step') as $name) {
if(!strlen((string) $attrs[$name])) unset($attrs[$name]);
}
}
// these attributes not valid for 'text' type
if($attrs['type'] == 'text') unset($attrs['step'], $attrs['min'], $attrs['max']);
if($note) $note = " <span class='details'>$note</span>";
if(!strlen($attrs['value'])) {
if(strlen($this->initValue)) {
$attrs['value'] = (int) $this->initValue; // Inputfield-only version
@@ -67,76 +82,125 @@ class InputfieldInteger extends Inputfield {
}
}
$out = "<input " . $this->getAttributesString($attrs) . " />"; // . $note;
$out = "<input " . $this->getAttributesString($attrs) . " />";
return $out;
}
/**
* Sanitize value
*
* @param string|int|float $value
* @return int
*
*/
protected function sanitizeValue($value) {
if(is_int($value)) return $value;
$value = trim($value);
if(!strlen("$value")) return '';
$negative = substr($value, 0, 1) === '-';
if($negative) $value = substr($value, 1);
if(!ctype_digit("$value")) $value = preg_replace('/[^\d,.]/', '', $value); // remove non digits, like commas, etc.
if($negative) $value = substr($value, 1);
// remove non digits, except commas and periods
if(!ctype_digit("$value")) $value = preg_replace('/[^\d,.]/', '', $value);
if(!strlen("$value")) return '';
if(strpos($value, '.') !== false || strpos($value, ',') !== false) $value = round($value);
if(strpos($value, '.') !== false || strpos($value, ',') !== false) $value = round((float) $value);
$value = (int) $value;
if($negative) $value = -1 * $value;
return $value;
}
/**
* Typecast value to integer
*
* @param string|int|float $value
* @return int
*
*/
protected function typeValue($value) {
return (int) $value;
}
/**
* Is current value considered empty?
*
* @return bool
*
*/
public function isEmpty() {
return strlen("{$this->value}") === 0;
$value = $this->val();
return strlen("$value") === 0;
}
/**
* Is current value in specified min/max range?
*
* @param int $value
* @return bool
*
*/
protected function isInRange($value) {
$inRange = true;
$min = $this->attr('min');
$max = $this->attr('max');
if(strlen("$value")) {
if(strlen("$min") && ((int) $value) < ((int) $min)) {
$inRange = false;
}
if(strlen("$max") && ((int) $value) > ((int) $max)) {
$inRange = false;
}
}
return $inRange;
if(!strlen("$value")) return true; // no value present yet
list($min, $max) = array($this->attr('min'), $this->attr('max'));
if(strlen("$min") && ($this->typeValue($value)) < ($this->typeValue($min))) return false;
if(strlen("$max") && ($this->typeValue($value)) > ($this->typeValue($max))) return false;
return true;
}
/**
* Set attribute
*
* @param array|string $key
* @param array|bool|int|string $value
* @return Inputfield
*
*/
public function setAttribute($key, $value) {
if($key == 'value') {
if($key === 'value') {
$value = $this->sanitizeValue($value);
if(strlen("$value") && !$this->isInRange($value)) {
$min = $this->attr('min');
$max = $this->attr('max');
$any = $this->_('any');
$any = $this->_('any'); // referring to “any” minimum or maximum number
if(!strlen("$min")) $min = $any;
if(!strlen("$max")) $max = $any;
$this->error(sprintf($this->_('Specified value %3$s removed because it is out of bounds (min=%1$s, max=%2$s)'), $min, $max, $value));
$value = $this->attr('value'); // restore previous value
$value = $this->val(); // restore previous value
}
} else if($key === 'min' || $key === 'max') {
if(strlen("$value")) {
$value = strpos("$value", '.') !== false ? (float) $value : (int) $value;
}
}
return parent::setAttribute($key, $value);
}
/**
* Set setting or attribute
*
* @param string $key
* @param mixed $value
* @return Inputfield|WireData
*
*/
public function set($key, $value) {
if($key == 'inputType') {
$this->attr('type', $value);
} else if($key == 'min' || $key == 'max') {
if(strlen("$value")) {
$value = strpos($value, '.') !== false ? (float) $value : (int) $value;
}
}
if($key === 'inputType') $this->attr('type', $value);
return parent::set($key, $value);
}
/**
* Inputfield configuration
*
* @return InputfieldWrapper
*
*/
public function getConfigInputfields() {
$inputfields = parent::getConfigInputfields();
$f = $this->wire('modules')->get('InputfieldRadios');
$modules = $this->wire()->modules;
/** @var InputfieldRadios $f */
$f = $modules->get('InputfieldRadios');
$f->attr('name', 'inputType');
$f->label = $this->_('Numeric Input Type');
$f->addOption('text', $this->_('Text'));
@@ -145,8 +209,9 @@ class InputfieldInteger extends Inputfield {
$f->description = $this->_('Choosing the "Number" type enables some additional client-side validation in browsers that support it.');
$f->columnWidth = 50;
$inputfields->add($f);
$f = $this->wire('modules')->get('InputfieldInteger');
/** @var InputfieldInteger $f */
$f = $modules->get('InputfieldInteger');
$f->attr('name', 'size');
$f->label = $this->_('Input Size');
$f->description = $this->_('Specify the size attribute for the input, or specify 0 for full width.');
@@ -157,7 +222,8 @@ class InputfieldInteger extends Inputfield {
$f->attr('type', 'number');
$inputfields->add($f);
$f = $this->wire('modules')->get('InputfieldText');
/** @var InputfieldText $f */
$f = $modules->get('InputfieldText');
$f->attr('name', 'min');
$f->attr('value', $this->attr('min'));
$f->label = $this->_('Minimum Value');
@@ -165,7 +231,7 @@ class InputfieldInteger extends Inputfield {
$f->columnWidth = 50;
$inputfields->add($f);
$f = $this->wire('modules')->get('InputfieldText');
$f = $modules->get('InputfieldText');
$f->attr('name', 'max');
$f->attr('value', $this->attr('max'));
$f->label = $this->_('Maximum Value');
@@ -174,7 +240,7 @@ class InputfieldInteger extends Inputfield {
$inputfields->add($f);
if($this->hasFieldtype === false) {
$f = $this->wire('modules')->get('InputfieldText');
$f = $modules->get('InputfieldText');
$f->attr('name', 'initValue');
$f->attr('value', $this->initValue);
$f->label = $this->_('Initial value');