XF options do not round-trip integer/boolean values as expected

Xon

Well-known member
Affected version
2.3.6
PHP:
var_dump(\XF::Options()->changeLogLength);

$option = Helper::find(\XF\Entity\Option::class, 'changeLogLength');
$option->option_value = 0;
var_dump($option->option_value);

Both of these will output a string type instead of the expected int type. This matters because xf-dev:generate-options-stub CLI command gives strongly typed hints, and phpstorm (and other php code formatting tools) will suggest to unwrap any casts. Except the underlying type is stringy so strict checks (=== / !==) will unexpectedly fail.

The solution appears for \XF\Entity\getOptionValue() and \XF\Entity\getDefaultValue() to call castOptionValue instead of the partial customized version of castOptionValue. Or if castOptionValue is too strict using isDataTypeNumeric before casting to an int
 
Last edited:
Something like:
PHP:
public function getOptionValue()
{
    $v = $this->option_value_;
    if ($this->isDataTypeNumeric())
    {
        return (int)$v;
    }
    else if ($this->data_type === 'bool')
    {
        return (bool)$v;
    }
    else if ($this->data_type === 'array')
    {
        $value = json_decode($v, true);
        if (!is_array($value))
        {
            return [];
        }

        return $value;
    }
   
    return $v;
}

But duplicating this code for getDefaultValue feels kinda wrong, especially as it is largely duplicating castOptionValue but without any throw statements.
 
Instead of a raw cast to int, something like strval(floatval($v)) + 0; should be used as that handles floats+ints
 
I just came across the same issue, would be nice if this could be fixed so we can use strict comparisons.

Maybe just add a param $throw to castOptionValue() and use that method for both getOptionValue() and getDefaultValue()?
 
I just came across the same issue, would be nice if this could be fixed so we can use strict comparisons.
I patched this behaviour in my StandardLib add-on with the v1.22.x version:

It is why my add-ons have started depending on v1.22.0+, as this simplifies a bunch of my code and stops phpstorm detecting a false positive about an unrequired type cast.
 
Back
Top Bottom