nachdem ich bereits die Listings um Properties und Hersteller-Daten erweitert habe, möchte ich auch Produkte die in Erlebniswelt-Slidern um diese Daten erweitern. Hierzu haben mir bisher hauptsächlich diese beidem Threads geholfen (danke!):
class SliderElementResolver extends ProductSliderCmsElementResolver
{
public function collect(CmsSlotEntity $slot, ResolverContext $resolverContext): ?CriteriaCollection
{
$criteriaCollection = new CriteriaCollection();
$config = $slot->getFieldConfig();
$products = $config->get('products');
if (!$products || $products->isMapped() || $products->getValue() === null) {
return null;
}
if ($products->isStatic() && $products->getValue()) {
$criteria = new Criteria($products->getValue());
$criteria->addAssociation('properties.group');
$criteria->addAssociation('manufacturer.media');
$criteriaCollection->add('product-slider' . '_' . $slot->getUniqueIdentifier(), ProductDefinition::class, $criteria);
}
return $criteriaCollection->all() ? $criteriaCollection : null;
}
}
Die Gruppierung der Daten erfolgt im bereits vorhandenen ProductEvents::PRODUCT_LOADED_EVENT Listener.
Eigentlich funktioniert das auch so. Was mich nur wundert ist, dass in $criteriaCollection->add der erste Parameter $key von mir hardcecodet mit product-slider geprefixt werden musste, obwohl hierfür in der Eltern-Klasse ProductSliderCmsElementResolver eine Konstante STATIC_SEARCH_KEY = "product-slider" existiert und diese dort auch als Prefix für $key genutzt wird.
Diese ist aber private, nicht protected und kann somit nicht genutzt werden. So ist das Ganze auf meiner Seite nicht sonderlich Update-resistent. Es gibt auch noch ein getType(), was ebenfalls ‚product-slider‘ zurückgibt - aber ebenfalls hard und nicht per STATIC_SEARCH_KEY.
Ist das von Shopware unsauber programmiert, oder mache ich hier grundsätzlich etwas falsch? (Worauf mich das private ja vielleicht hinweisen möchte…)
als Hinweis: Die grundsätzliche Herangehensweise ist mir beim Update auf die 6.3.1.0 auf die Füße gefallen, weshalb ich dank @Shyim nun Dependency Injection benutze. Falls noch mal wer hierdrüber stolpert:
class MyResolver
{
/** @var ProductSliderCmsElementResolver $elementResolver */
private $elementResolver;
public function __construct(ProductSliderCmsElementResolver $elementResolver)
{
$this->elementResolver = $elementResolver;
}
public function getType(): string
{
return $this->elementResolver->getType();
}
public function collect(CmsSlotEntity $slot, ResolverContext $resolverContext): ?CriteriaCollection
{
$criteriaCollection = new CriteriaCollection();
$config = $slot->getFieldConfig();
$products = $config->get('products');
if (!$products || $products->isMapped() || $products->getValue() === null) {
return null;
}
if ($products->isStatic() && $products->getValue()) {
$criteria = new Criteria($products->getValue());
$criteria->addAssociation('properties.group');
$criteria->addAssociation('manufacturer.media');
$criteriaCollection->add('product-slider' . '_' . $slot->getUniqueIdentifier(), ProductDefinition::class, $criteria);
}
return $criteriaCollection->all() ? $criteriaCollection : null;
}
public function enrich(CmsSlotEntity $slot, ResolverContext $resolverContext, ElementDataCollection $result): void
{
$this->elementResolver->enrich($slot, $resolverContext, $result);
}
}
@devnullroot Danke für deinen Code. Hast du deinen Service über das Decorator Pattern registriert? Falls nein, muss noch etwas anderes in services.xml stehen?
Sorry, hab grade so gar keine Zeit, aber der Code sollte, bis auf Namensanpassungen, genau so laufen. Bei mir ist jedenfalls nicht mehr drin, hab eben kurz nachgesehen.
Kurzer Nachtrag: Der Code funktioniert NICHT bei Slidern mit dynamischen Produktgruppen. Hinter der if Abfrage mit isStatic() habe ich als Fallback die Original-Methode aufgerufen:
Die dynamischen Produktgruppen werden da über die private Methode “collectByProductStream” abgefrühstückt. Die habe ich nicht angepasst/überschrieben und auch keine Möglichkeit gefunden hier $criteria zu erweitern
Ich habe heute diese Funktion ebenfalls benötigt. Vielen dank für die Ausführung. Es ist aber grundsätzlich nicht nötig den collect komplett neu zu definieren. Hier besteht aus meiner sicht auch eher das Problem das bei einem update der collect im zweifels fall auch angepasst werden muss. es Funktioniert auch mit dem Parent collect welcher dann nur um die Association erweiter
public function collect(CmsSlotEntity $slot, ResolverContext $resolverContext): ?CriteriaCollection
{
$criteriaCollection = $this->resolver->collect($slot, $resolverContext);
foreach ($criteriaCollection as $productCriteria) {
foreach ($productCriteria as $criteria) {
$criteria->addAssociation('properties.group');
}
}
return $criteriaCollection;
}
hier sollten dann auch die Probleme mit den Privaten Klassen Constanten nicht mehr existieren und bei mir funktioniert auch ein dynamische Produkt Gruppe
Moin zusammen,
ich bin auch gerade dabei einen Resolver mit den Decorator Pattern zu erweitern ich möchte das Hersteller-Logo rein bekommen. Also die URL dazu. Leider wird mir die URL bisher noch nicht ausgeben.
Bisher habe ich das hier gebaut:
$criteria->addAssociation('manufacturer.media');
$criteriaCollection = new CriteriaCollection();
$criteriaCollection->add('product_' . $slot->getUniqueIdentifier(), ProductDefinition::class, $criteria);
Ein dump($criteriaCollection) gibt mir nur leere Felder bei manufacturer.media aus.
Wie kann ich die Werte bekommen?
Muss ich einen API call machen?
ich stelle gerade fest, dass der Produkt-Slider, der vom Cross Selling verwendet wird, in der neuen Version (6.4.x) Probleme macht. Vorher konnte der Herstellername dort angezeigt werden, jetzt nicht mehr.
Ob dynamische Produktgruppe oder nicht ist nach meinen Tests egal.
Weiß jemand, was geändert muss, bzw. was sich seit Shopware 6.4 verändert hat?
Edit: Hier nochmal der Inhalt des Product Slider Resolvers:
<?php
declare(strict_types=1);
namespace SupplierInfoListing\Resolver;
use Shopware\Core\Content\Cms\Aggregate\CmsSlot\CmsSlotEntity;
use Shopware\Core\Content\Cms\DataResolver\CriteriaCollection;
use Shopware\Core\Content\Cms\DataResolver\ResolverContext\ResolverContext;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Content\Product\ProductDefinition;
use Shopware\Core\Content\Cms\DataResolver\Element\ElementDataCollection;
use Shopware\Core\Content\Product\Cms\ProductSliderCmsElementResolver;
class SupplierInfoListingProductSlider
{
/** @var ProductSliderCmsElementResolver $elementResolver */
private $elementResolver;
public function __construct(ProductSliderCmsElementResolver $elementResolver)
{
$this->elementResolver = $elementResolver;
}
public function getType(): string
{
return $this->elementResolver->getType();
}
public function collect(CmsSlotEntity $slot, ResolverContext $resolverContext): ?CriteriaCollection
{
$criteriaCollection = $this->elementResolver->collect($slot, $resolverContext);
foreach ($criteriaCollection as $productCriteria) {
foreach ($productCriteria as $criteria) {
$criteria->addAssociation('manufacturer');
$criteria->addAssociation('manufacturer.media');
}
}
return $criteriaCollection;
}
public function enrich(CmsSlotEntity $slot, ResolverContext $resolverContext, ElementDataCollection $result): void
{
$this->elementResolver->enrich($slot, $resolverContext, $result);
}
}
Hallo, ich bin neu in der Welt von Shopware und versuche ein Theme nach Designvorlage umzusetzen. Nun bin ich auf das gleiche Probleme wie oben beschrieben gestoßen. Ich brauch den manufacturer name in eine ProductBox, bzw. zukünftig auch in einem Product Slider. Die ProductBoxResolver Klasse hab ich analog zu hier beschriebenen SliderResolver klasse angelegt.
Wie muss die service.xml aussehen, damit der Service richtig registriert wird?
Könnte mir jemand auf die Sprünge helfen oder mir einen Tipp geben, wo ich weitere Informationen dazu finde?
Die service IDs und die classes SupplierInfoListingProductBox, SupplierInfoListingProductSlider, SupplierInfoListingManufacturerListing und SupplierInfoListingManufacturerSearch heißen bei dir wahrscheinlich anders, das musst du dann anpassen.
leider bin ich mit dem CrossSellingCmsElementResolver bisher nicht weitergekommen.
Ich bin noch nicht so firm mit Shopware 6, dass ich das Problem alleine lösen kann.
ich habe auch Probleme, ich habe alles mögliche ausprobiert aber mein Subscriber befüllt die Daten nicht, ich möchte die Produkt-Slider in Erlebniswelten (mit dynamische Produktgruppen befüllt) erweitern. Der Slider greift ja auf die box-standard und wenn ich da ein dump auf die Produkte mache, dann bekommen ich bei Manufacturer z.B. null.
Meine Subscriber Events die ich bis jetzt ausprobiert habe: