When I try to run an import job in Magento 2 I get this weird error and I can't find a solution anywhere else. We are importing with Firebear Improved Import/Export v.3.1.6. When I press "Edit & Run" on an existing import job I'm sending to a different page where I get this error message. What I can see from the error message is that something is wrong in this file "AbstractOptionsField.php".
1 Answer
I don't know if you fixed the problem, but I will post my solution in case someone else has the same problem.
Problem
I encountered the problem with Magento 2.3.5-p2 with PHP 7.3 and Firebear/ImportExport v3.1.6. I think that the main issue is that the extension versions below 3.2.0 are not fully compatible with Magento 2.3.2 onwards as it's stated in the extension changelog:
3.2.0 PHP 7.3 is fully supported. Besides, the extension is compatible with Magento 2.3.3. We’ve also added timestamp added for each log entry and a selector that allows removing product associated images from the server if the extension constantly imports new ones. All attributes are now included.
The full exception is:
Warning: Illegal string offset '__disableTmpl' in /vendor/magento/module-ui/Component/Form/Element/AbstractOptionsField.php on line 69 {"report_id":"8fda31ec65ff454e4ab0079d62b33273fb75cf30f01f640582de51ebf99835a8","exception":"[object] (Exception(code: 0): Warning: Illegal string offset '__disableTmpl' in /vendor/magento/module-ui/Component/Form/Element/AbstractOptionsField.php on line 69 at /vendor/magento/framework/App/ErrorHandler.php:61)"} []
The problem actually comes from Firebear\ImportExport\Ui\Component\Listing\Column\Duplicate\Options.php
toOptionArray() method, because it's returning an array of strings and you can see that line 69 in AbstractOptionsField.php
is trying to add a value to an array and thus throwing the Illegal string offset
error.
AbstractOptionsField.php
public function prepare()
{
$config = $this->getData('config');
if (isset($this->options)) {
if (!isset($config['options'])) {
$config['options'] = [];
}
if ($this->options instanceof OptionSourceInterface) {
$options = $this->options->toOptionArray();
} else {
$options = array_values($this->options);
}
if (empty($config['rawOptions'])) {
$options = $this->convertOptionsValueToString($options);
}
array_walk(
$options,
function (&$item) {
*line 69* $item['__disableTmpl'] = true;
}
);
$config['options'] = array_values(array_replace_recursive($config['options'], $options));
}
$this->setData('config', (array)$config);
parent::prepare();
}
Options.php
class Options implements OptionSourceInterface{
/**
* @var array
*/
protected $options;
/**
* @var array
*/
protected $duplicateFields = [
'product' => ['sku', 'scope', 'url_key'],
'customer' => [\Magento\CustomerImportExport\Model\Import\Customer::COLUMN_EMAIL],
'address' => [],
'composite' => [\Magento\CustomerImportExport\Model\Import\Customer::COLUMN_EMAIL],
'cmsPage' => []
];
/**
* Get options
*
* @return array
*/
public function toOptionArray()
{
$newOptions = [];
foreach ($this->duplicateFields as $fields) {
$newOptions = array_merge($newOptions, $fields);
}
$this->options = array_unique($newOptions);
return $this->options; // options looks like this -> ['sku', 'scope', 'url_key', 'email']
}
}
Solution
I fixed this by creating a preference for the Firebear\ImportExport\Ui\Component\Listing\Column\Duplicate\Option.php
, overriding the toOptionArray()
method, and returning the options in the required format.
Preference
class DuplicateOptions extends Options
{
/**
* Get options
*
* @return array
*/
public function toOptionArray()
{
$newOptions = [];
foreach ($this->duplicateFields as $fields) {
$newOptions = array_merge($newOptions, $fields);
}
$newOptions = array_unique($newOptions);
$newOptions = $this->convertOptionsToRightFormat($newOptions);
$this->options = $newOptions;
return $this->options;
}
/**
* Converts the option array to the required format from AbstractOptionsField.php
* @param array $array
* @return array
*/
private function convertOptionsToRightFormat(array $array){
for($i = 0; $i < count($array); $i++) {
$array[$i] = ['label' => $array[$i], 'value' => $array[$i]];
}
return $array;
}
}
di.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<preference for="Firebear\ImportExport\Ui\Component\Listing\Column\Duplicate\Options" type="Vendor\Module\Model\DuplicateOptions"/>
</config>
Don't know if this is the cleanest solution, but it will work temporarily. The best one will be just to update the extension to version >= 3.2.0.
P.S. This problem is fixed in >= Magento 2.4.0