Fixed htmlspecialchars_decode() expects parameter 1 to be string, array given

Sim

Well-known member
Importing an old vb3.8 database into a fresh XF2.0.9 install for testing my addon - getting the following error:

Bash:
$ xf xf:import
Starting import from vBulletin 3.7, 3.8 (Beta)...
 - Step  1 of 26: User groups               00:00:00 [11]
 - Step  2 of 26: Custom user fields        00:00:01 [14]
 - Step  3 of 26: Users                     00:00:05 [1,000] 1.10%
                                                                                      
  [ErrorException]                                                                     
  [E_WARNING] htmlspecialchars_decode() expects parameter 1 to be string, array given 
                                                                                      

xf:import
 
  • ErrorException: [E_WARNING] htmlspecialchars_decode() expects parameter 1 to be string, array given
  • src/addons/XFI/Import/Importer/vBulletin.php:1326

Code:
Stack trace
#0 [internal function]: XF::handlePhpError(2, '[E_WARNING] htm...', '...', 1326, Array)
#1 src/addons/XFI/Import/Importer/vBulletin.php(1326): htmlspecialchars_decode(Array)
#2 src/addons/XFI/Import/Importer/vBulletin.php(1177): XFI\Import\Importer\vBulletin->mapUserFields(Array, Array)
#3 src/addons/XFI/Import/Importer/vBulletin.php(1008): XFI\Import\Importer\vBulletin->setupImportUser(Array, Object(XF\Import\StepState), Array)
#4 src/XF/Import/Runner.php(160): XFI\Import\Importer\vBulletin->stepUsers(Object(XF\Import\StepState), Array, 8)
#5 src/XF/Import/Runner.php(74): XF\Import\Runner->runStep('users', Object(XF\Import\StepState), 8)
#6 src/XF/Cli/Command/Import.php(66): XF\Import\Runner->run()
#7 src/vendor/symfony/console/Command/Command.php(242): XF\Cli\Command\Import->execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#8 src/vendor/symfony/console/Application.php(843): Symfony\Component\Console\Command\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#9 src/vendor/symfony/console/Application.php(193): Symfony\Component\Console\Application->doRunCommand(Object(XF\Cli\Command\Import), Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#10 src/vendor/symfony/console/Application.php(117): Symfony\Component\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#11 src/XF/Cli/Runner.php(63): Symfony\Component\Console\Application->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#12 cmd.php(15): XF\Cli\Runner->run()
#13 {main}
 
My guess is that the problem lies in the mapUserFields function which applies htmlspecialchars_decode to the $fieldValue, but that function expects a string while we may be passing an array when dealing with multiple choice user fields.

I'm thinking there needs to be some array handling logic added around the call to htmlspecialchars_decode.

PHP:
protected function mapUserFields(array $user, array $profileFieldChoices)
    {
        $fieldValues = [];

        foreach ($this->typeMap('user_field') AS $fieldId => $newFieldId)
        {
            $fieldName = 'field' . $fieldId;

            if ($user[$fieldName] !== '')
            {
                if (array_key_exists($fieldId, $profileFieldChoices))
                {
                    // choices

                    $fieldInfo = $profileFieldChoices[$fieldId];

                    if ($fieldInfo['multiple'])
                    {
                        // multiple choice
                        $fieldValue = []; // <---- WHOOPS - $fieldValue is an array!

                        foreach ($fieldInfo['choices'] AS $bitValue => $stringValue)
                        {
                            if ($user[$fieldName] & $bitValue)
                            {
                                $fieldValue[$stringValue] = $stringValue;
                            }
                        }
                    }
                    else if (array_key_exists($user[$fieldName], $fieldInfo['choices']))
                    {
                        $fieldValue = $fieldInfo['choices'][$user[$fieldName]];
                    }
                }
                else
                {
                    // freeform input

                    $fieldValue = $user[$fieldName];
                }

                if (!empty($fieldValue))
                {
                    $fieldValues[$newFieldId] = htmlspecialchars_decode($fieldValue); // <---- FAILING HERE ... $fieldValue MUST BE A STRING - need to adjust this code to handle arrays
                }
            }
        }

        return $fieldValues;
    }
 
Top Bottom