Frage zu ListProductService dekorieren

Ich habe mit folgendem Script den ListProductService um weitere Bilder dekoriert. Das funktioniert auch soweit. Es existieren Objekte mit weiteren Bilddaten.

Nun habe ich Verständnisprobleme wie ich in meinem Smarty Template darauf zugreife. Kann mir jemand ein konkretes Beispiel geben?

<?php
namespace ShopwarePlugins\AmbicoAddDataToProduct\StoreFrontBundle; use Shopware\Bundle\StoreFrontBundle\Service\ListProductServiceInterface; use Shopware\Bundle\StoreFrontBundle\Service\MediaServiceInterface; use Shopware\Bundle\StoreFrontBundle\Struct; class ListProductService implements ListProductServiceInterface {     private $service;     private $mediaService;     function \_\_construct(ListProductServiceInterface $service, MediaServiceInterface $mediaService) {         $this-\>service = $service;         $this-\>mediaService = $mediaService;     }     public function getList(array $numbers, Struct\ProductContextInterface $context) {         $products = $this-\>service-\>getList($numbers, $context);         $media = $this-\>mediaService-\>getProductsMedia($products, $context);         foreach($numbers as $number) {             $product = $products[$number];                          if(isset($media[$number])) {                 $attribute = new Struct\Attribute(['images' =\> $media[$number]]);                 $product-\>addAttribute('moreimages', $attribute);             }             $products[$number] = $product;         }         return $products;     }     public function get($number, Struct\ProductContextInterface $context) {         $products = $this-\>getList([$number], $context);         return array\_shift($products);     } }   In meinem Smarty Template sehe ich mit folgendem Script das Objekte weiterer Bilder existieren. Möchte ich jedoch auf ein Feld zugreifen kommt folgende Fehlermeldung  Cannot use object of type Shopware\Bundle\StoreFrontBundle\Struct\Attribute as array in ...   {if $sArticle.attributes.moreimages} {$ambicomoreimages = $sArticle.attributes.moreimages} {$moreimages=$ambicomoreimages-\>get('images')} {foreach $moreimages as $image} {$image|@var\_dump} {/foreach} {/if}      

An die Template-Engine wird ein Objekt übergeben. Die kommt an der Stelle jedoch nur mit einem Array klar. Es gibt in Shopware einen StructConverter den kannst du nutzen.

1 Like

Hi,

muss das Thema nochmal aufrollen.

Ich komme hier nicht ganz klar damit. Ich habe das wie folgt proboert:

 

 $attribute = new Struct\Attribute(['images' =\> $media[$number]]); $convattribute = $this-\>legacyStructConverter-\>convertMediaStruct( $attribute ); $product-\>addAttribute('moreimages', $convattribute);

Kann mir bitte jemand nochmal Support  geben?

Danke!

 &nbsp;

Hat für den 

legacyStructConverter jemand eine lösung? Ich komme an dieser stelle auch nicht weiter Der Aufbau des Converters wie mtruebenbach aufgeführt hat müsste doch korrekt sein. So jedenfalls ist er auch in sArticles hinterlegt.

Ich konnte mein Problem lösen. Das ganze hat ohne den legacy struct converter geklappt. Mein Problem lag beim zugriff auf die Variable aus dem Template heraus. in der getList des eigenen ListProductServiceInterface muss man ganz normal wie bereits oben beschrieben folgendes aufrufen:

$attribute = new Struct\Attribute(['images' => $media[$number]]);
$product->addAttribute('peaddon', $attribute);

Danach kann man im Template über folgenden Befehl darauf zugreifen;

{$peAddon = $sArticle.attributes.peaddon}
{$peAddon->get('images')|var_dump}

 

1 Like

Da ich jetzt auch vor dem gleichen Problem stand, habe ich nun das gefunden, was ihr glaube ich gesucht habt. Es ist aus meiner Sicht nicht ganz sauber gelöst in Smarty das ‘get’ zu benutzen. Man könnte stattdessen toArray benutzen. So wird nicht das Struct-Object in Smarty übergeben, sondern direkt der Inhalt dessen.

$attribute = new Struct\Attribute(['images' => $media[$number]]);
$product->addAttribute('peaddon', $attribute->toArray());

 

Nun stand ich vor der gleichen Herausforderung und habe mal den legacyStructConverter eingesetzt.

public function getList(array $numbers, Struct\ProductContextInterface $context)
{
    $products = $this->service->getList($numbers, $context);
    $media = $this->mediaService->getProductsMedia($products, $context);

    /**@var $product Struct\ListProduct */
    foreach ($numbers as $number) {
        $product = $products[$number];

        if (isset($media[$number])) {

            foreach ($media[$number] as $key => $image) {
                $image_array[$key] = Shopware()->Container()->get('legacy_struct_converter')->convertMediaStruct(
                    $image
                );
            }

            $attribute = new Struct\Attribute(['images' => $image_array]);
            $product->addAttribute('images', $attribute);
        }
    }

    return $products;
}

In der View kann dann wie folgt zugegriffen werden:

{if $sArticle.attributes.images}
    {$images = $sArticle.attributes.images->get('images')}

    {foreach $images as $image}
        
    {/foreach}
{/if}

 

Eine kleine Ergänzung noch dazu. Das $image_array muss vor der foreach Schleife immer wieder resettet werden, da ansonsten die Bilder vorhergehender Produkte auch noch beigemischt werden. Folgende getList Funktion macht also mehr Sinn.

public function getList(array $numbers, Struct\ProductContextInterface $context)
{
    $products = $this->service->getList($numbers, $context);
    $media = $this->mediaService->getProductsMedia($products, $context);

    /**@var $product Struct\ListProduct */
    foreach ($numbers as $number) {
        $product = $products[$number];

        if (isset($media[$number])) {

            $image_array = null;

            foreach ($media[$number] as $key => $image) {
                $image_array[$key] = Shopware()->Container()->get('legacy_struct_converter')->convertMediaStruct(
                    $image
                );
            }

            $attribute = new Struct\Attribute(['images' => $image_array]);
            $product->addAttribute('images', $attribute);
        }
    }

    return $products;
}