28 May 2015 von teiling88
Snippets

AdditionalTextService aus dem StoreFrontBundle überschreiben.

Folgende Ausgangssituation - ich möchte in der Klasse StoreFrontBundle / Service / Core / AdditionalTextService.php die Funktion buildTextDynamic() ändern. Leider ist die Funktion als private deklariert und lässt sich so einfach nicht anpassen. Die einzige, mir bekannte, Lösung ist den Service von Shopware über ein Plugin auszutauschen. Ein Beispiel-Plugin erstellen wir im weiteren Verlauf. Folgende Verzeichnisstruktur innerhalb des Plugins AdditionalTextService benötigen wir:

  • Bootstrap.php
  • Bundle/StoreFrontBundle/AdditionalTextService.php
Die entwickelte Bootstrap.php sieht so aus:
<?php
use ShopwarePlugins\AdditionalTextService\Bundle\StoreFrontBundle\AdditionalTextService;

class Shopware_Plugins_Core_AdditionalTextService_Bootstrap extends Shopware_Components_Plugin_Bootstrap
{
    public function afterInit()
    {
        $this->get('Loader')->registerNamespace(
            'ShopwarePlugins\AdditionalTextService',
            $this->Path()
        );
    }

    public function install()
    {
        $this->subscribeEvent(
            'Enlight_Bootstrap_InitResource_shopware_storefront.additional_text_service',
            'replaceAdditionalTextService'
        );
        return true;
    }

    public function replaceAdditionalTextService(Enlight_Event_EventArgs $args)
    {
        $configuratorService = Shopware()->Container()->get('shopware_storefront.configurator_service');
        $additionalTextService = new AdditionalTextService($configuratorService);
        Shopware()->Container()->set('shopware_storefront.additional_text_service', $additionalTextService);
    }
}
Die entwickelte AdditionalTextService.php sieht so aus:
<?php
namespace ShopwarePlugins\AdditionalTextService\Bundle\StoreFrontBundle;

use Shopware\Bundle\StoreFrontBundle\Service\AdditionalTextServiceInterface;
use Shopware\Bundle\StoreFrontBundle\Service\ConfiguratorServiceInterface;
use Shopware\Bundle\StoreFrontBundle\Struct\ListProduct;
use Shopware\Bundle\StoreFrontBundle\Struct\Configurator\Group;
use Shopware\Bundle\StoreFrontBundle\Struct\ShopContextInterface;

class AdditionalTextService implements AdditionalTextServiceInterface
{
    /**
     * @var ConfiguratorServiceInterface
     */
    private $configuratorService;

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

    /**
     * @inheritdoc
     */
    public function buildAdditionalText(ListProduct $product, ShopContextInterface $context)
    {
        $products = $this->buildAdditionalTextLists([$product], $context);

        return array_shift($products);
    }

    /**
     * @inheritdoc
     */
    public function buildAdditionalTextLists($products, ShopContextInterface $context)
    {
        $required = [];
        foreach ($products as &$product) {
            if (!$product->getAdditional()) {
                $required[] = $product;
            }
        }

        if (empty($required)) {
            return $products;
        }

        $configurations = $this->configuratorService->getProductsConfigurations(
            $required,
            $context
        );

        /**@var $required ListProduct[] */
        foreach ($required as &$product) {
            if (!array_key_exists($product->getNumber(), $configurations)) {
                continue;
            }

            $config = $configurations[$product->getNumber()];

            $product->setAdditional($this->buildTextDynamic($config));
        }

        return $products;
    }

    /**
     * @param Group[] $configurations
     *
     * @return string
     */
    private function buildTextDynamic($configurations)
    {
        $text = [];
        foreach ($configurations as $group) {
            foreach ($group->getOptions() as $option) {
                $text[] = $group->getName() . ': ' . $option->getName();
            }
        }

        return implode(' ', $text);
    }
}
Über das Event Enlight_Bootstrap_InitResource können wir uns in die Initialisierung des Services einklicken. Wir verwenden bewusst keinen AfterInitResource Event, da wir die Instanz von Shopware vollständig überschreiben. In unserer Funktion replaceAdditionalTextService erstellen wir nun eine Instanz von unserem angepassten AdditionalTextService. Die vorhandene Abhängigkeit ConfiguratorServiceInterface lässt sich einfach über den Shopware Container auflösen. Fertig ist der austausch des AdditionalTextServies :-)    

Loading…