Skip to content

Commit

Permalink
castTypeSoftly() - Support magic floats and magic ints
Browse files Browse the repository at this point in the history
  • Loading branch information
totten committed Feb 17, 2023
1 parent 1f28277 commit f0c3117
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 5 deletions.
30 changes: 25 additions & 5 deletions Civi/Api4/Utils/ReflectionUtils.php
Original file line number Diff line number Diff line change
Expand Up @@ -217,19 +217,26 @@ public static function findMethodHelpers($class, string $prefix): iterable {
}

/**
* Cast the $value to the preferred $type.
* Cast the $value to the preferred $type (if we're fairly confident).
*
* This is like PHP's `settype()` but totally not. It only casts in narrow circumstances.
* This reflects an opinion that some casts are better than others.
* This reflects an opinion that some castings are better than others.
*
* - Good: 1 => TRUE
* - Bad: 'hello' => TRUE
* These will be converted:
*
* cast('123', 'int') => 123
* cast('123.4', 'float') => 123.4
* cast('0', 'bool') => FALSE
* cast(1, 'bool') => TRUE
*
* However, a string like 'hello' will never cast to bool, int, or float -- because that's
* a senseless request. We'll leave that to someone else to figure.
*
* @param mixed $value
* @param array $paramInfo
* @return mixed
* If the $value is agreeable to casting according to a type-rule from $paramInfo, then
* we return the converted value. Otherwise, leave return the original value.
* we return the converted value. Otherwise, return the original value.
*/
public static function castTypeSoftly($value, array $paramInfo) {
if (count($paramInfo['type'] ?? []) !== 1) {
Expand All @@ -243,6 +250,19 @@ public static function castTypeSoftly($value, array $paramInfo) {
return (bool) $value;
}
break;

case 'int':
if (is_numeric($value)) {
return (int) $value;
}
break;

case 'float':
if (is_numeric($value)) {
return (float) $value;
}
break;

}

return $value;
Expand Down
68 changes: 68 additions & 0 deletions tests/phpunit/api/v4/Action/AbstractActionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,26 @@ protected function createExample(): AbstractAction {
*/
protected $magicBool;

/**
* @var float
*/
protected $simpleFloat;

/**
* @var float
*/
protected $magicFloat;

/**
* @var int
*/
protected $simpleInt;

/**
* @var int
*/
protected $magicInt;

/**
* @param bool $simpleBool
*/
Expand All @@ -48,6 +68,22 @@ public function setSimpleBool(bool $simpleBool) {
return $this;
}

/**
* @param float $simpleFloat
*/
public function setSimpleFloat(float $simpleFloat) {
$this->simpleFloat = $simpleFloat;
return $this;
}

/**
* @param int $simpleInt
*/
public function setSimpleInt(int $simpleInt) {
$this->simpleInt = $simpleInt;
return $this;
}

/**
* @param \Civi\Api4\Generic\Result $result
*/
Expand All @@ -71,6 +107,38 @@ public function getCastingExamples(): array {
],
];

$exs['float'] = [
['simpleFloat', 'magicFloat'],
[
// Each item is an example: [$inputValue, $expectValue]
[0, 0.0],
['0', 0.0],
[100, 100.0],
['200', 200.0],
[300.5, 300.5],
['400.6', 400.6],
],
];

$exs['int'] = [
['simpleInt', 'magicInt'],
[
// Each item is an example: [$inputValue, $expectValue]
[0, 0],
['0', 0],
[100, 100],
['200', 200],
[300.5, 300],
['400.6', 400],
],
];

// Magic fields are nullable. Not saying that's good or bad. It just is.
$exs['null'] = [
['magicBool', 'magicFloat', 'magicInt'],
[[NULL, NULL]],
];

return $exs;
}

Expand Down

0 comments on commit f0c3117

Please sign in to comment.