I have used an event Subscriber for Product. Using Store-API I want to search for products. So I get an Error when I send this API request :
POST : http://localhost/store-api/search?search=Logo
Error :
"code": "0",
"status": "500",
"title": "Internal Server Error",
"detail": "Shopware\\Core\\Framework\\Struct\\Struct::getExtension(): Return value must be of type ?Shopware\\Core\\Framework\\Struct\\Struct, array returned",
"meta": {
"trace": [
{
"file": "/var/www/html/vendor/shopware/core/System/SalesChannel/Api/StructEncoder.php",
"line": 254,
"function": "getExtension",
"class": "Shopware\\Core\\Framework\\Struct\\Struct",
"type": "->",
"args": [
"mediaLogos"
]
}
]
Subscriber File:
class ProductSubscriber implements EventSubscriberInterface
{
private EntityRepositoryInterface $productRepository;
private EntityRepositoryInterface $mediaRepository;
public function __construct(
EntityRepositoryInterface $productRepository,
EntityRepositoryInterface $mediaRepository
) {
$this->productRepository = $productRepository;
$this->mediaRepository = $mediaRepository;
}
public static function getSubscribedEvents(): array
{
return [
'sales_channel.' . ProductEvents::PRODUCT_LOADED_EVENT => 'salesChannelLoaded',
];
}
public function salesChannelLoaded(SalesChannelEntityLoadedEvent $event): void
{
/** @var SalesChannelProductEntity $product */
$products = $event->getEntities();
foreach ($products as $product) {
$id = $product->getParentId() ? $product->getParentId() : $product->getId();
$criteria = new Criteria([$id]);
$criteria->addAssociation('medialogos');
$productEntity = $this->productRepository->search(
$criteria,
\Shopware\Core\Framework\Context::createDefaultContext()
)->first();
$prodExtensions = $productEntity->getExtensions();
if (isset($prodExtensions['medialogos']) && !empty($prodExtensions['medialogos'])) {
$mediaLogos = $prodExtensions['medialogos']->getElements();
foreach ($mediaLogos as &$mLogo) {
if ($mLogo->logo) {
$mediaEntity = $this->mediaRepository->search(
(new Criteria([$mLogo->logo])),
\Shopware\Core\Framework\Context::createDefaultContext()
)->first();
$mLogo->logo = $mediaEntity;
}
}
$prodExtensions['medialogos'] = $mediaLogos;
$product->setExtensions($prodExtensions);
}
}
}
}
How can I solve this bug ? Could you help me please ?
The argument for setExtensions
should be Struct[]
but you are giving array[]
. You want to wrap $mediaLogos
in an ArrayStruct
.
$prodExtensions['medialogos'] = new ArrayStruct($mediaLogos);
Alternatively you might not even want to call getElements
on $prodExtensions['medialogos']
since I assume it's an instance of EntityCollection
which is in turn a subclass of Struct
that also implements IteratorAggregate
.
So you could simply iterate like that and wouldn't even have to set the extension again:
foreach ($prodExtensions['medialogos'] as $mLogo) {
// ...
$mLogo->logo = $mediaEntity;
// ...
}