# Wie Helper Klasse manipulieren / hooken?

**URL:** <https://forum.shopware.com/t/wie-helper-klasse-manipulieren-hooken/29568>\
**Category:** Programmierung\
**Created:** [12. August 2015 um 14:26 UTC](https://forum.shopware.com/t/wie-helper-klasse-manipulieren-hooken/29568 "2015-08-12T14:26:24Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![ottscho](https://avatars.discourse-cdn.com/v4/letter/o/7ba0ec/32.png) [@ottscho](https://forum.shopware.com/u/ottscho)\
**Post date:** [12. August 2015 um 14:26 UTC](https://forum.shopware.com/t/wie-helper-klasse-manipulieren-hooken/29568/1 "2015-08-12T14:26:24Z")

</div>

Hallo Community, ich möchte ein HelperClass in SearchBundleDBAL modifizieren. Am besten hooken und den Rückgabewert ändern. Ist das überhaupt möglich? Mein Versuch geht nicht. Welche Alternativen hätte ich? Bin Dankbar für jeden Vorschlag. ` public function install() { $this-\>subscribeEvent( //'Shopware\_Bundle\_SearchBundleDBAL\_PriceHelper::getSelection::after', 'Shopware\Bundle\SearchBundleDBAL\PriceHelper::getSelection::after', 'afterGetSelection' ); return true; } public function afterGetSelection(Enlight\_Hook\_HookArgs $arguments) { $temp = $arguments-\>getReturn(); // Debug ob\_start(); var\_dump($temp); $datei = fopen("./logs/ott.log","a+"); fwrite($datei, ob\_get\_contents() . "\n"); ob\_end\_clean(); $arguments-\>setReturn($temp); } `

---

<div class="post-metadata">

**Author:** ![DanielNogel](https://avatars.discourse-cdn.com/v4/letter/d/96bed5/32.png) [@DanielNogel](https://forum.shopware.com/u/DanielNogel)\
**Post date:** [12. August 2015 um 14:30 UTC](https://forum.shopware.com/t/wie-helper-klasse-manipulieren-hooken/29568/2 "2015-08-12T14:30:56Z")

</div>

Hi, in den Bundles wird nicht mehr gehookt, stattdessen nutzen wir einen Decorator-Pattern, der euch für public-Methoden das gleiche erlaubt: [https://developers.shopware.com/develop … xtensions/](https://developers.shopware.com/developers-guide/shopware-5-core-service-extensions/) Besten Gruß, Daniel

---

<div class="post-metadata">

**Author:** ![EikeBrandtWarneke](https://avatars.discourse-cdn.com/v4/letter/e/cdc98d/32.png) [@EikeBrandtWarneke](https://forum.shopware.com/u/EikeBrandtWarneke)\
**Post date:** [12. August 2015 um 14:33 UTC](https://forum.shopware.com/t/wie-helper-klasse-manipulieren-hooken/29568/3 "2015-08-12T14:33:11Z")

</div>

Ein Hinweis von meiner Seite - weil ich anfangs Probleme hatte den richtigen service zu finden: Unter /engine/Shopware/Bundle/SearchBundleDBAL/services.xml werden alle services dieses bundles registriert. Du suchst: ` <service id="shopware_searchdbal.search_price_helper_dbal" class="Shopware\Bundle\SearchBundleDBAL\PriceHelper">
            <argument type="service" id="dbal_connection"></argument>
            <argument type="service" id="config"></argument>
        </service>` Viele Grüße

---

<div class="post-metadata">

**Author:** ![ottscho](https://avatars.discourse-cdn.com/v4/letter/o/7ba0ec/32.png) [@ottscho](https://forum.shopware.com/u/ottscho)\
**Post date:** [12. August 2015 um 15:53 UTC](https://forum.shopware.com/t/wie-helper-klasse-manipulieren-hooken/29568/4 "2015-08-12T15:53:35Z")

</div>

danke für die Tips. Soweit sollte ich es versatanden haben: ` public function install() { $this-\>subscribeEvent( 'Enlight\_Bootstrap\_AfterInitResource\_shopware\_searchdbal.search\_price\_helper\_dbal', 'modPriceHelper', 500 ); return true; } public function afterInit() { $this-\>get('Loader')-\>registerNamespace('ShopwarePlugins\OttTestZwei', $this-\>Path()); } public function modPriceHelper() { $coreHelper = Shopware()-\>Container()-\>get('shopware\_searchdbal.search\_price\_helper\_dbal'); //$newHelper = new ModPriceHelper($coreHelper); $newHelper = $coreHelper; Shopware()-\>Container()-\>set('shopware\_searchdbal.search\_price\_helper\_dbal', $newHelper); ` Mir ist das mit dem ersetzen / ändern noch nicht ganz klar. Gibt es dazu noch ein weiteres Beispiel? Im Prinzip will ich genau diesen Funktion ändern. [https://github.com/shopware/shopware/bl … er.php#L66](https://github.com/shopware/shopware/blob/5.0/engine/Shopware/Bundle/SearchBundleDBAL/PriceHelper.php#L66) Vielen Dank euch.

---

<div class="post-metadata">

**Author:** ![ottscho](https://avatars.discourse-cdn.com/v4/letter/o/7ba0ec/32.png) [@ottscho](https://forum.shopware.com/u/ottscho)\
**Post date:** [12. August 2015 um 18:10 UTC](https://forum.shopware.com/t/wie-helper-klasse-manipulieren-hooken/29568/5 "2015-08-12T18:10:18Z")

</div>

hier mal mein versuch. OttTestZwei\Bootstrap.php [code]\<?php use ShopwarePlugins\OttTestZwei\SearchBundleDBAL\ModPriceHelper;

class Shopware\_Plugins\_Frontend\_OttTestZwei\_Bootstrap extends Shopware\_Components\_Plugin\_Bootstrap  
{

```
public function install()
{

    $this->subscribeEvent( 'Enlight\_Bootstrap\_AfterInitResource\_shopware\_searchdbal.search\_price\_helper\_dbal', 'modPriceHelper', 500 ); return true; } public function afterInit() { $this-\>get('Loader')-\>registerNamespace('ShopwarePlugins\OttTestZwei', $this-\>Path()); } public function modPriceHelper() { $coreHelper = Shopware()-\>Container()-\>get('shopware\_searchdbal.search\_price\_helper\_dbal'); $newHelper = new ModPriceHelper($coreHelper, NULL); Shopware()-\>Container()-\>set('shopware\_searchdbal.search\_price\_helper\_dbal', $newHelper); } [/code] OttTestZwei\SearchBundleDBAL\ModPriceHelper.php [code]<?php namespace Shopware\Bundle\SearchBundleDBAL;

```

use Shopware\Bundle\StoreFrontBundle\Struct;

class ModPriceHelper implements PriceHelperInterface  
{

```
/**
 * @var Connection
 */
private $connection;
/**
 * @var \Shopware_Components_Config
 */
private $config;
/**
 * @param Connection $connection
 * @param \Shopware_Components_Config $config
 */
public function __construct(Connection $connection, \Shopware_Components_Config $config)
{
    $this->connection = $connection; $this-\>config = $config; } /\*\* \* @inheritdoc \*/ public function getSelection(Struct\ShopContextInterface $context) { $fallback = $context-\>getFallbackCustomerGroup(); $current = $context-\>getCurrentCustomerGroup(); $currency = $context-\>getCurrency(); $priceField = 'defaultPrice.price'; if ($fallback-\>getId() != $current-\>getId()) { $priceField = 'IFNULL(customerPrice.price, defaultPrice.price)'; } $discount = $current-\>useDiscount() ? $current-\>getPercentageDiscount() : 0; $considerMinPurchase = $this-\>config-\>get('calculateCheapestPriceWithMinPurchase'); //rounded to filter this value correctly // =\> 2,99999999 displayed as 3,- € but won't be displayed with a filter on price \>= 3,- € return 'ROUND(' . //customer group price (with fallback switch) $priceField . //multiplied with the variant min purchase ($considerMinPurchase ? ' \* availableVariant.minpurchase' : '') . //multiplied with the percentage price group discount ' \* ((100 - IFNULL(priceGroup.discount, 0)) / 100)' . //multiplied with the product tax if the current customer group should see gross prices ($current-\>displayGrossPrices() ? " \* ((tax.tax + 100) / 100)" : '') . //multiplied with the percentage discount of the current customer group ($discount ? " \* " . (100 - (float) $discount) / 100 : '') . //multiplied with the shop currency factor ($currency-\>getFactor() ? " \* " . $currency-\>getFactor() : '') . ', 2)'; } /\*\* \* @inheritdoc \*/ public function joinPrices( QueryBuilder $query, Struct\ShopContextInterface $context ) { if ($query-\>hasState(self::STATE\_INCLUDES\_CHEAPEST\_PRICE)) { return; } $this-\>joinDefaultPrices($query, $context); $graduation = 'customerPrice.from = 1'; if ($this-\>config-\>get('useLastGraduationForCheapestPrice')) { $graduation = "customerPrice.to = 'beliebig'"; } $query-\>leftJoin( 'product', 's\_articles\_prices', 'customerPrice', 'customerPrice.articleID = product.id AND customerPrice.pricegroup = :currentCustomerGroup AND ' . $graduation . ' AND availableVariant.id = customerPrice.articledetailsID' ); $query-\>leftJoin( 'product', 's\_core\_pricegroups\_discounts', 'priceGroup', 'priceGroup.groupID = product.pricegroupID AND priceGroup.discountstart = 1 AND priceGroup.customergroupID = :priceGroupCustomerGroup AND product.pricegroupActive = 1' ); $query-\>setParameter(':currentCustomerGroup', $context-\>getCurrentCustomerGroup()-\>getKey()) -\>setParameter(':priceGroupCustomerGroup', $context-\>getCurrentCustomerGroup()-\>getId()); $query-\>addState(self::STATE\_INCLUDES\_CHEAPEST\_PRICE); } /\*\* \* @inheritdoc \*/ public function joinDefaultPrices(QueryBuilder $query, Struct\ShopContextInterface $context) { if ($query-\>hasState(self::STATE\_INCLUDES\_DEFAULT\_PRICE)) { return; } $this-\>joinAvailableVariant($query); $graduation = 'defaultPrice.from = 1'; if ($this-\>config-\>get('useLastGraduationForCheapestPrice')) { $graduation = "defaultPrice.to = 'beliebig'"; } $query-\>innerJoin( 'product', 's\_articles\_prices', 'defaultPrice', 'defaultPrice.articledetailsID = availableVariant.id AND defaultPrice.pricegroup = :fallbackCustomerGroup AND ' . $graduation ); $query-\>setParameter( ':fallbackCustomerGroup', $context-\>getFallbackCustomerGroup()-\>getKey() ); $query-\>addState(self::STATE\_INCLUDES\_DEFAULT\_PRICE); } /\*\* \* @inheritdoc \*/ public function joinAvailableVariant(QueryBuilder $query) { if ($query-\>hasState(self::STATE\_INCLUDES\_AVAILABLE\_VARIANT)) { return; } $stockCondition = ''; if ($this-\>config-\>get('hideNoInstock')) { $stockCondition = 'AND (product.laststock \* availableVariant.instock) \>= (product.laststock \* availableVariant.minpurchase)'; } $query-\>innerJoin( 'product', 's\_articles\_details', 'availableVariant', 'availableVariant.articleID = product.id AND availableVariant.active = 1 ' . $stockCondition ); $query-\>addState(self::STATE\_INCLUDES\_AVAILABLE\_VARIANT); } } [/code] Fehler: Fatal error: Class 'ShopwarePlugins\OttTestZwei\SearchBundleDBAL\ModPriceHelper' not found in /var/www/clients/client1/web8/web/engine/Shopware/Plugins/Local/Frontend/OttTestZwei/Bootstrap.php on line 31 503 Service Unavailable Ich hoffe der Ansatz stimmt.
```

---

<div class="post-metadata">

**Author:** ![EikeBrandtWarneke](https://avatars.discourse-cdn.com/v4/letter/e/cdc98d/32.png) [@EikeBrandtWarneke](https://forum.shopware.com/u/EikeBrandtWarneke)\
**Post date:** [12. August 2015 um 18:27 UTC](https://forum.shopware.com/t/wie-helper-klasse-manipulieren-hooken/29568/6 "2015-08-12T18:27:02Z")

</div>

Ohne deinen code weiter analysiert zu haben: deine namespaces sind falsch. Ein Beispiel: subscriber: [http://pastebin.com/tYLZrCtd](http://pastebin.com/tYLZrCtd) list product service: [http://pastebin.com/pnfUn0mn](http://pastebin.com/pnfUn0mn) plugin service: [http://pastebin.com/VKkr5rAt](http://pastebin.com/VKkr5rAt) Viele Grüße

---

<div class="post-metadata">

**Author:** ![ottscho](https://avatars.discourse-cdn.com/v4/letter/o/7ba0ec/32.png) [@ottscho](https://forum.shopware.com/u/ottscho)\
**Post date:** [24. August 2015 um 20:23 UTC](https://forum.shopware.com/t/wie-helper-klasse-manipulieren-hooken/29568/7 "2015-08-24T20:23:42Z")

</div>

Danke, ich habe es nun mit eurer Hilfe hinbekommen. Eine Frage habe ich aber noch. Ich möchte nur eine Funktion anpassen. [https://github.com/shopware/shopware/bl … er.php#L66](https://github.com/shopware/shopware/blob/5.0/engine/Shopware/Bundle/SearchBundleDBAL/PriceHelper.php#L66) Muss ich dann trotzdem alle anderen Funktionen auch in meiner eigenen Klasse angeben? Wenn ich es nicht machte kommt ein Fehler. Ich habe die nun einfach vom Original rein kopiert. Geht erst mal. Wie ist es wenn es mehrere Plugins gibt, die hier an der Stelle Änderungen vornehmen? Überschreiben die sich dann gegenseitig? Nur Informativ. Danke

---

<div class="post-metadata">

**Author:** ![hec](https://avatars.discourse-cdn.com/v4/letter/h/e274bd/32.png) [@hec](https://forum.shopware.com/u/hec)\
**Post date:** [25. August 2015 um 09:14 UTC](https://forum.shopware.com/t/wie-helper-klasse-manipulieren-hooken/29568/8 "2015-08-25T09:14:07Z")

</div>

[quote=„ottscho“] Muss ich dann trotzdem alle anderen Funktionen auch in meiner eigenen Klasse angeben? Wenn ich es nicht machte kommt ein Fehler. Ich habe die nun einfach vom Original rein kopiert. Geht erst mal. [/quote] Kannst du nicht von der Original-Klasse erben? Also in der Art: ` class ModPriceHelper extends PriceHelper implements PriceHelperInterface ` Grüße, Sven

---

<div class="post-metadata">

**Author:** ![ottscho](https://avatars.discourse-cdn.com/v4/letter/o/7ba0ec/32.png) [@ottscho](https://forum.shopware.com/u/ottscho)\
**Post date:** [25. August 2015 um 11:20 UTC](https://forum.shopware.com/t/wie-helper-klasse-manipulieren-hooken/29568/9 "2015-08-25T11:20:51Z")

</div>

doch, geht. Danke.

---

<div class="post-metadata">

**Author:** ![EikeBrandtWarneke](https://avatars.discourse-cdn.com/v4/letter/e/cdc98d/32.png) [@EikeBrandtWarneke](https://forum.shopware.com/u/EikeBrandtWarneke)\
**Post date:** [25. August 2015 um 13:30 UTC](https://forum.shopware.com/t/wie-helper-klasse-manipulieren-hooken/29568/10 "2015-08-25T13:30:28Z")

</div>

Du musst dann nur aufpassen, falls andere Plugins die gleiche Klasse dekorieren. Viele Grüße

---

<div class="post-metadata">

**Author:** ![DanielNogel](https://avatars.discourse-cdn.com/v4/letter/d/96bed5/32.png) [@DanielNogel](https://forum.shopware.com/u/DanielNogel)\
**Post date:** [25. August 2015 um 19:26 UTC](https://forum.shopware.com/t/wie-helper-klasse-manipulieren-hooken/29568/11 "2015-08-25T19:26:44Z")

</div>

Hi, das Erben und „reinkopieren“ von Code ist beides tödlich für die Erweiterbarkeit. In beiden Fällen bindest du dich hart an die Implementierung der Shopware-Original-Klasse. Wenn ein anderes Plugin (vor dir) die Klasse dekoriert, deaktivierst du dessen Erweiterbarkeit damit de facto. Die einzige (richtige) Möglichkeit ist es, sich den Original-Service in seinen Service zu injecten und den dann ggf. intern aufzurufen. Beispiel hängt an, bitte nur diesen Weg gehen. Gruß, Daniel

---

<div class="post-metadata">

**Author:** ![ottscho](https://avatars.discourse-cdn.com/v4/letter/o/7ba0ec/32.png) [@ottscho](https://forum.shopware.com/u/ottscho)\
**Post date:** [25. August 2015 um 19:49 UTC](https://forum.shopware.com/t/wie-helper-klasse-manipulieren-hooken/29568/12 "2015-08-25T19:49:15Z")

</div>

D.h., wenn ich es korrekt verstehe, ich manipuliere nicht den Code der Funktion, sondern fange den Rückgabewert der Funktion ab, und passe diesen an? ` $result = $this-\>decorated-\>getList($numbers, $context); //Hier den Inhalt manipulieren -\> $result return $result; ` So wie ein Hook After?

---

<div class="post-metadata">

**Author:** ![DanielNogel](https://avatars.discourse-cdn.com/v4/letter/d/96bed5/32.png) [@DanielNogel](https://forum.shopware.com/u/DanielNogel)\
**Post date:** [25. August 2015 um 19:59 UTC](https://forum.shopware.com/t/wie-helper-klasse-manipulieren-hooken/29568/13 "2015-08-25T19:59:27Z")

</div>

Hi, ja, genau. So kannst du quasi before / after und replace-Hooks haben, ohne wirklich Hooks zu haben 🙂 Replace (also gar nicht die Original-Methode aufrufen) ist aber weiterhin böse 🙂 Schönen Abend! Daniel

---

<div class="post-metadata">

**Author:** ![maforum](https://avatars.discourse-cdn.com/v4/letter/m/ecc23a/32.png) [@maforum](https://forum.shopware.com/u/maforum)\
**Post date:** [11. Mai 2017 um 13:45 UTC](https://forum.shopware.com/t/wie-helper-klasse-manipulieren-hooken/29568/14 "2017-05-11T13:45:51Z")

</div>

> [@Daniel Nögel schrieb:](https://forum.shopware.com/profile/4010/Daniel%20N%C3%B6gel "Daniel%20N%C3%B6gel")
> 
> Hi,
> 
> das Erben und „reinkopieren“ von Code ist beides tödlich für die Erweiterbarkeit. In beiden Fällen bindest du dich hart an die Implementierung der Shopware-Original-Klasse. Wenn ein anderes Plugin (vor dir) die Klasse dekoriert, deaktivierst du dessen Erweiterbarkeit damit de facto.
> 
> Die einzige (richtige) Möglichkeit ist es, sich den Original-Service in seinen Service zu injecten und den dann ggf. intern aufzurufen.
> 
> Beispiel hängt an, bitte nur diesen Weg gehen.
> 
> &nbsp;

Hi,

gibt es das Beispiel, um nur eine Funktion der Helperklasse auszutauschen noch?

LG&nbsp;
