Shopware Plugin 101 | Service extensions

Wer schon mal im neuen Shopware Daten im Listing oder in der Suche erweitern wollte, wird schon auf die serivce extensions gestoßen sein. Neue Services wie StoreFrontBundle enthalten keine Hooks mehr, sondern werden mit einem Dekorater ersetzt oder erweitert.

Pluginstruktur

Base File

Wie üblich besteht unser Plugin aus einer Base File, in unserem Fall einfach:

MiHoListingErweiterung.php
<?php

namespace MiHoListingErweiterung;

use Shopware\Components\Plugin;

class MiHoListingErweiterung extends Plugin
{
}

welche sich im Root Verzeichnis des Plugins unter custom/plugins/MiHoListingErweiterung befindet.

plugin.xml

<?xml version="1.0" encoding="utf-8"?>
<plugin xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="https://raw.githubusercontent.com/shopware/shopware/5.3/engine/Shopware/Components/Plugin/schema/plugin.xsd">
    <label lang="de">MiHo Listing Erweiterung</label>
    <label lang="en">MiHo listing extension</label>

    <version>1.0.0</version>
    <copyright>(c) by Micha Hobert</copyright>
    <license>MIT</license>
    <link>https://www.the-cake-shop.de</link>
    <author>Micha Hobert</author>
    <compatibility minVersion="5.3.0"/>

    <changelog version="1.0.0">
        <changes lang="de">Erstveröffentlichung</changes>
        <changes lang="en">First release</changes>
    </changelog>
</plugin>

Diese kommt ebenfalls in das Root Verzeichnis. Nun fehlen uns nur noch die die services.xml und die ListProductService.php – die services.xml enthält die Symfony DIC service container und in der File ListProductService erweitern wir die Produktliste um ein Attribut.

services.xml

<container xmlns="http://symfony.com/schema/dic/services"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">

    <services>
        <service id="shopware_storefront.list_product_service_decorator"
                 class="MiHoListingErweiterung\Bundle\StoreFrontBundle\ListProductService"
                 decorates="shopware_storefront.list_product_service"
                 public="false">
            <argument type="service" id="shopware_storefront.list_product_service_decorator.inner"/>
        </service>
    </services>
</container>

Wir dekorieren hier also den ListProductService und zwar in MiHoListingErweiterung\Bundle\StoreFrontBundle\ListProductService 

Die verschiedenen StoreFrontBundle Services finden wir unter engine/Shopware/Bundle/StoreFrontBundle/services.xml

Wollten wir den kompletten Service überschreiben, würden wir das wie folgt tun:

<services>
    <service id="shopware_storefront.list_product_service" class="MiHoListingErweiterung\Bundle\StoreFrontBundle\ListProductService" />
</services>

 

ListProductService.php

Wie bereits gesagt erweitern wir hier den ListProductService. Ich habe hier im Beispiel keine wirkliche Logik eingebaut, lediglich ein Attribut (miho_listing_erweiterung) mit einem Array gesetzt.

<?php

namespace MiHoListingErweiterung\Bundle\StoreFrontBundle;

use Shopware\Bundle\StoreFrontBundle\Service\ListProductServiceInterface;
use Shopware\Bundle\StoreFrontBundle\Struct;

class ListProductService implements ListProductServiceInterface
{
	/**
	 * @var ListProductServiceInterface
	 */
	private $service;


	/**
	 * @param ListProductServiceInterface $service
	 */
	public function __construct(ListProductServiceInterface $service)
	{
		$this->service = $service;
	}

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

		/**@var $product Struct\ListProduct*/
		foreach ($products as $product) {
			$productId = $product->getId();

			//TODO Hier kommt Deine Logik hin
			$array['yourstuff'] = $this->getArticleVars($productId);


			$array_struct = new Struct\Attribute($array);
			$product->addAttribute('miho_listing_erweiterung', $array_struct);
		}
		return $products;
	}

	/**
	 * Private method
	 */
	private function getArticleVars($articleID)
	{

		$tmparray = [0 => 'MyStuff'.$articleID];
		return $tmparray;
	}


	/**
     * @inheritdoc
     */
    public function get($number, Struct\ProductContextInterface $context)
    {
        $products = $this->getList([$number], $context);
        return array_shift($products);
    }
}

Das ganze können wir dann im Frontend mit:

{if $sArticle.attributes.miho_listing_erweiterung}
    {$test = $sArticle.attributes.miho_listing_erweiterung->get('yourstuff')}
    {$test.0}
{/if}

auslesen/ausgeben. Ob Ihr die Daten direkt im Plugin verarbeitet (Resources/views) oder im Theme ist dann euch überlassen.

Fazit

Besonders interessant ist das für alle Entwickler, welche vorab auf Events im Listing zugegriffen haben um Daten der Artikel zu erweitern. Beispielsweise über die Events

Shopware_Modules_Articles_sGetArticlesByCategory_FilterLoopEnd

oder

Enlight_Controller_Action_Widgets_Listing_listingCount

dies hat für Shopware 5.2 noch funktioniert – in 5.3 müsst Ihr aber den Weg über die service extensions gehen.

 

Plugin Download

Ihr könnt das Plugin HIER herunterladen

Eine Antwort auf „Shopware Plugin 101 | Service extensions“

  1. Was muss denn für ein Template angelegt werden, um das Listing im Plugin überschreiben? Ich habe

    {$test = $sArticle.attributes.miho_listing_erweiterung->get(‚yourstuff‘)}
    {$test.0}

    in die Detailseite im Theme hinzugefügt. Hätte es aber gerne im Plugin, um es themeunabhängig zu haben.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert