Provider with numeric indices appends instead of replace
Serializator opened this issue · comments
I was trying to use the MagePal\GoogleTagManager\DataLayer\OrderData\OrderProvider
through DI to add my own provider to the $orderProviders
argument, which by itself works.
I want to add a key to each element inside the "transactionProducts" sub-array from the "gtm.orderCompleted" event, but it appended two new elements onto the "transactionProducts" sub-array rather than override the elements at the specified indices.
Because MagePal\GoogleTagManager\DataLayer\OrderData\OrderProvider
uses array_replace_recursive
, it appends instead of replace numeric indices.
PHP Docs
_array_merge_recursive() merges the elements of one or more arrays together so that the values of one are appended to the end of the previous one. It returns the resulting array.
If the input arrays have the same string keys, then the values for these keys are merged together into an array, and this is done recursively, so that if one of the values is an array itself, the function will merge it with a corresponding entry in another array too. If, however, the arrays have the same numeric key, the later value will not overwrite the original value, but will be appended._
Using "array_replace_recursive" resolves the issue, but I'm not certain about backward compatibility.
Magento version #: 2.3.2
Edition (EE, CE, OS, etc): EE
Expected behavior:
...
"transactionProducts" => [
[
"name" => "A Product",
"foobar" => "I'm foobar"
]
]
...
Actual behavior:
...
"transactionProducts" => [
[
"name" => "A Product"
],
[
"foobar" => "I'm foobar"
]
]
...
Steps to reproduce:
- Write a order provider using the
MagePal\GoogleTagManager\DataLayer\OrderData\OrderAbstract
class - Add the order provider to
orderProviders
inMagePal\GoogleTagManager\DataLayer\OrderData\OrderProvider
using DI -
public function getData() { return ["transactionProducts" => [ 0 => [ "foobar" => "I'm foobar" ] ]]; }
@Serializator ... this is kinda limitation in the design, originally I was using array_merge_recursive and switch to array_merge in the latest version because if you tried to merge any layer that has 'event' then you would stop the events from triggering and cause a lot more issues.
You can easily accomplish this using OrderItemProvider
MagePal\GoogleTagManager\DataLayer\OrderData\OrderItemProvider
Eg
/**
* @package MagePal\DataLayer\Data\OrderData
*/
class OrderItemProvider extends OrderItemAbstract
{
/**
* @var Product
*/
private $productHelper;
/**
* ItemProvider constructor.
* @param Product $productHelper
*/
public function __construct(
Product $productHelper
) {
$this->productHelper = $productHelper;
}
/**
* @return array
*/
public function getData()
{
$product = $this->getItem()->getProduct();
return [
'url' => $product->getProductUrl(),
'image_url' => $this->productHelper->getImageUrl($product)
];
}
}