Option einer Eigenschaft bei einem Artikel im Kategorie-Listing

Hallo zusammen,

 

ich suche die Möglichkeit eine Option einer Eigenschaft bei einem Artikel im Kategorie-Listing ausgeben zu können.

Wie komme ich, zum Beispiel, an die “Farbe” (Eigenschaft) “rot” (Option) bei einem T-Shirt?

Irgendwelche Tipps oder Links ins Forum. Ich habe leider nicht das passende gefunden.

Vielen Dank im Voraus.

Hi, am einfachsten per Plugin. Haben wir soweit fertig, kommt in kürze im Store.

Grüße Matthias

 

Hallo,

man könnte den ListProductService dekorieren:

/**
 * @param array $numbers
 * @param Struct\ProductContextInterface $context
 * @return Struct\ListProduct[]
*/
public function getList(array $numbers, Struct\ProductContextInterface $context)
{
    $products = $this->service->getList($numbers, $context);

    foreach ($products as $product) {
        $productProperties = $this->getProductProperties($product->getId());

        $product->addAttribute('properties_attribute', new Struct\Attribute(['productProperties' => $productProperties]));
    }

    return $products;
}

 

In der “getProductProperties” Funktion könnte man jetzt die Eigenschaften und deren Optionen aus dem DB auslesen:

SELECT fo.id AS option_id, fo.name AS option_name, fv.id AS value_id, fv.value AS value_name, m.path AS value_path

FROM s_filter_articles AS fa
LEFT JOIN s_filter_values AS fv ON fv.id = fa.valueID
LEFT JOIN s_filter_options AS fo ON fo.id = fv.optionID
LEFT JOIN s_media AS m ON m.id = fv.media_id
WHERE fa.articleID = (int)$articleId
ORDER BY fv.optionID, fv.position

Die Eigenschaften Optionen müssen noch vernünftig strukturiert werden!

 

Alternativ kann man auch das gleiche mit einem Event machen:

$this->subscribeEvent(
    'Enlight_Controller_Action_PostDispatchSecure_Frontend',
    'onPostDispatchSecureFrontend'
);

Dabei aber auch Produkte beachten die nachgeladen werden:

// Event on dispatch widgets
$this->subscribeEvent(
    'Enlight_Controller_Action_PostDispatchSecure_Widgets',
    'onPostDispatchSecureWidgets'
);

 

Besten Grüß,
Nikita

Hi Nikita,

danke für deinen Tipp. Ich habe mich mal an einem Mini-Plugin zu dem Thema versucht. Heruntergeladen werden kann es hier: 

https://portalsystems-my.sharepoint.com/personal/kevin_schmid_portalsystems_de/_layouts/15/guestaccess.aspx?guestaccesstoken=yKcEotnNzUWrMNhRYFopvBHULiWCE4%2FH2JZo%2F%2FrLSH0%3D&docid=0aaa5ed3ec6c44fa9b50ea7e70e0febdd&rev=1&expiration=2016-08-20T15%3A05%3A07.000Z

Der Zugriff im Frontend könnte folgendermaßen aussehen: 

{if $sArticle.attributes.product_properties}
{$sArticlesProps = $sArticle.attributes.product_properties->get('kschmidExtendListing')}
{if $sArticlesProps.articleProp.Zutaten_0}
Wert auslesen: {$sArticlesProps.articleProp.Zutaten_0}
{/if}
{/if} 

Es besteht somit über den Part $sArticlesProps.articleProp Zugriff auf jede angelegte Gruppe. 

Sollte es z.B. eine Eigenschaft names “Geschmack” geben und zu einem Artikel 3 Zuordnungen existieren, kann der Zugriff folgendermaßen erfolgen: 

$sArticlesProps.articleProp.Geschmack_0 oder $sArticlesProps.articleProp.Geschmack_1 oder $sArticlesProps.articleProp.Geschmack_2 

!!!BITTE BEACHTEN!!! 

Das ist mein erstes Plugin und lediglich ein Test. Ich mache das die Tage ggf. noch runder, tue mir momentan allerdings etwas schwer mit der Plugindokumentation zur Pluginentwicklung in 5.2 und den zur Verfügung stehenden Ressourcen. Als Denkanstoß oder für ein Testsystem kann es natürlich gerne verwendet werden. 

Über eine Rückmeldung, ob das überhaupt Shopware-konform ist würde ich mich hinsichtlich meiner “Lernkurve” auch freuen. Werde erst im September bei Shopware zu einer Plugin-Schulung sein :) 

Danke euch.

Liebe Grüße

Kevin

Hi,

der Ansatz ist schon sehr gut. Hier noch ein kleines Improvement. Für die Produkt Eigenschaften gibt es auch einen Service welcher dann auch die Übersetzungen berücksichtigt. Du hast dann jedoch in dem Attribute das Set des Produktes drin stehen und nicht direkt die Gruppen, daher müsstest du dann erst noch von dem Set auf die Gruppe zugreifen. Ein weiterer Vorteil ist die Performance da in dem nachfolgendem Beispiel nur 1x Abfrage gegen die Datenbank für alle Produkte gesendet wird.

Solltest du mit den Struct Klassen des Property-Sets nicht zurecht kommen oder es zu Fehlern führt, so kann du einfach ein json_decode(json_encode($struct), true) machen und du bekommst das ganze Element als Array.

 

service = $service;
        $this->propertyService = $propertyService;
    }

    public function getList(array $numbers, ProductContextInterface $context)
    {
        $products = $this->service->getList($numbers, $context);
        $properties = $this->propertyService->getList($products, $context);
        foreach ($products as $product) {
            $attribute = new Attribute();
            $product->addAttribute('properties_attribute', $attribute);

            if (isset($properties[$product->getNumber()])) {
                $attribute->set('productProperties', $properties[$product->getNumber()]);
            }
        }

        return $products;
    }

    public function get($number, ProductContextInterface $context)
    {
        return array_shift($this->getList([$number], $context));
    }
}

 

 

 

Hi Oliver,

vielen Dank für dein Feedback. Werde die Einbindung des Service für die Produkteigenschaften einmal testen heute Mittag. Habe mir nämlich selbst auch schon gedacht, dass für jedes Produkt immer eine Abfrage gegen die DB nicht wirklich toll ist für einen produktiven Betrieb. Hier tue ich mir momentan aber noch etwas schwer die nötigen Infos zur Shopwarearchitektur zu bekommen. Aber mit jedem bisschen lernt man ja weiter. 

Stelle die neue Version dann für alle zur Verfügung, sobald ich das eingebaut habe. Können sicherlich auch einige kostenfrei nutzen.
Vielen Dank nochmal!

Liebe Grüße

Kevin

Hi Oliver,

herzlichen Dank nochmals für deinen Tipp. Habe wie versprochen das Plugin nochmals ausgetauscht und nutze nun auch den Service für die Eigenschaften.

Lasse mir von meinem Service alle Gruppen zurückgeben, die ich im smarty dann bequem durchlaufen kann. Ich werde mir hierzu mal noch einige Gedanken hinsichtlich Konfigurationsoptionen machen und dann mit einem vorgefertigen Template ausliefern, sodass diese Erweiterung auch Anwender ohne Template-Kenntnisse nutzen können. 

Für alle die es interessiert und die das Plugin gerne herunterladen möchten im aktuellen Stand, möchte ich gerne einen Beispielausruf aus smarty vorstellen: 

{if $sArticle.attributes.kschmidExtendListing}
        {$sArticleProperties = $sArticle.attributes.kschmidExtendListing->get('productProperties')}
        {foreach $sArticleProperties as $propertyGroup}
              {if $propertyGroup->getName() == "Zutaten" || $propertyGroup->getName() == "Inhalt"}
                      {$propertyGroup->getName()}
                      {$myOptions = ""}
                      {foreach $propertyGroup->getOptions() as $propertyOption}
                              {$myOptions = $myOptions|cat: $propertyOption->getName()|cat:", "}
                      {/foreach}
                      {$lengthOpt = $myOptions|count_characters - 1}
                      {$myOptions|substr:0:$lengthOpt}
              {/if}
        {/foreach}
{/if}

Denke damit sollte alles gesagt sein zu dem bisherigen Plugin. 

Liebe Grüße

Kevin

1 „Gefällt mir“

@KevinS86 schrieb:

Hi Oliver,

herzlichen Dank nochmals für deinen Tipp. Habe wie versprochen das Plugin nochmals ausgetauscht und nutze nun auch den Service für die Eigenschaften.

https://www.dropbox.com/s/9gx88k122hxm0du/KSchmidExtendListing.zip?dl=0

Lasse mir von meinem Service alle Gruppen zurückgeben, die ich im smarty dann bequem durchlaufen kann. Ich werde mir hierzu mal noch einige Gedanken hinsichtlich Konfigurationsoptionen machen und dann mit einem vorgefertigen Template ausliefern, sodass diese Erweiterung auch Anwender ohne Template-Kenntnisse nutzen können. 

Für alle die es interessiert und die das Plugin gerne herunterladen möchten im aktuellen Stand, möchte ich gerne einen Beispielausruf aus smarty vorstellen: 

{if $sArticle.attributes.kschmidExtendListing}
{$sArticleProperties = $sArticle.attributes.kschmidExtendListing->get(‚productProperties‘)}
{foreach $sArticleProperties as $propertyGroup}
{if $propertyGroup->getName() == „Zutaten“ || $propertyGroup->getName() == „Inhalt“}
{$propertyGroup->getName()}
{$myOptions = „“}
{foreach $propertyGroup->getOptions() as $propertyOption}
{$myOptions = $myOptions|cat: $propertyOption->getName()|cat:", "}
{/foreach}
{$lengthOpt = $myOptions|count_characters - 1}
{$myOptions|substr:0:$lengthOpt}
{/if}
{/foreach}
{/if}

Denke damit sollte alles gesagt sein zu dem bisherigen Plugin. 

Liebe Grüße

Kevin

Hallo @KevinS86‍ und [@Oliver Skroblin](http://forum.shopware.com/profile/1871/Oliver Skroblin „Oliver Skroblin“)‍ ,

kommt man so auch an die eigenen Attribute des Option - Wertes (s_filter_values_attributes) auf der Artikel - Detailseite ran? Ausgelesen werden Sie prinzipiell mit {$propertyOption|@var_dump} :

object(Shopware\Bundle\StoreFrontBundle\Struct\Property\Option)#1593 (5) { ["id":protected]=> int(7) ["name":protected]=> string(13) "Hervorgehoben" ["media":protected]=> NULL ["position":protected]=> int(4) ["attributes":protected]=> array(1) { ["core"]=> object(Shopware\Bundle\StoreFrontBundle\Struct\Attribute)#1592 (1) { ["storage":protected]=> array(3) { ["id"]=> string(1) "1" ["valueID"]=> string(1) "7" ["my_attribute"]=> string(3) "abc" } } } } 

Aufrufe ala: {$propertyOption.attributes.core->get(„my_attribute“)} schlagen aber fehl Blush.

Beste Grüße

Sebastian

Vielen Dank für den Quellcode!

Ich habe das Plugin bei mir umgesetzt und ein wenig an meine Anforderungen angepasst, funktioniert jetzt super!

Einen kleinen Tipp noch:

Ich habe die Zeile

{$lengthOpt = $myOptions|count_characters - 1}

durch folgende ersetzt:

{$lengthOpt = ($myOptions|count_characters:true) - 2}

Grund ist, dass der Wert von count_characters im Standard auf „False“ steht, wodurch Whitespace bei der Berechnung nicht berücksichtigt wird. Daher war bei mir die Ausgabe zu kurz. Durch das :True zählt er auch Leerzeichen mit. Daher auch am Ende die „- 2“, da wir ja nach dem Komma noch ein Leerzeichen anfügen.

Ich habe noch eine Verbesserung:

Mit folgendem Code fällt die Rechnerei vollkommen weg:

{$myOptions = ""}
    {foreach $propertyGroup->getOptions() as $propertyOption}
        {if $propertyOption@last}
            {$myOptions = $myOptions|cat: $propertyOption->getName()}
        {else}
            {$myOptions = $myOptions|cat: $propertyOption->getName()|cat:", "}
        {/if}
    {/foreach}
    {$myOptions}

Die Funktion $propertyOption@last prüft, ob es sich um das letzte Element in der ForEach-Schleife handelt. In diesem Fall wird kein ", " mehr angehängt. Also kann zum Schluss ganz einfach die Variable $myOptions ausgegeben werden!

Ich hoffe, dass ich vielleicht jemandem helfen konnte :slight_smile:

Hallo @KevinS86 ,

leider funktioniert der Link nicht mehr.
Kannst du das PlugIn hier nochmal zur Verfügung stellen?
Ich finde es sehr interessant und würde es mir gerne ansehen.

Besten dank,
herzliche Grüße

@sschreier schrieb:

Aufrufe ala: {$propertyOption.attributes.core->get(„my_attribute“)} schlagen aber fehl Blush.

Beste Grüße

Sebastian

 

Auch wenns schon etwas spät it, versuch mal:

{if $propertyOption->hasAttribute('core')}
    {$propertyOption->getAttribute('core')->get('my_attribute')}
{/if}

 

gibt’s das Plugin noch irgendwo zum runterladen?
bräuchte sowas aktuell auch…