Wie kann die Plugin-Konfiguration z.B. bei einem Update manuell geändert werden?

Beispiel: ein installiertes Plugin erhält ein Update und möchte veraltete Werte in seiner eigenen Konfiguration, die vom Nutzer gesetzt wurden, durch neue Werte ersetzen.

Der Zugriff auf die Config im Plugin erfolgt ja z.B. mit

$this->Config()->get('key');

Leider lassen sich entsprechend andere Methoden genutzt, die Werte aber nicht in die Config zurückschreiben:

$this->Config()->set('key', 'val');
// ODER
$this->Config()->offsetSet('key', 'val');

Weiss jemand ob und wie das möglich ist?

Eine Möglichkeit wäre die Werte direkt in der entsprechenden Tabelle zu updaten.

// für Config Werte ohne Scope

$sql = "UPDATE `s_core_config_elements` SET `value` = ? WHERE `name` = ?";
Shopware()->Db()->query($sql, array(serialize('val'), 'key'));

// für Werte mit Scope und Shop ID

$sql = "UPDATE `s_core_config_values` val
        INNER JOIN `s_core_config_elements` el ON el.`id` = val.`element_id`
        SET val.`value` = ? 
        WHERE el.`name` = ? AND val.`shop_id` = ?";
Shopware()->Db()->query($sql, array(serialize('val'), 'key', 1));

Zu beachten ist, dass man die Werte serialized in die Tabelle schreibt.

Gibt es eine “sauberere” Möglichkeit?

Warum hat man Zugriff auf $this->Config(); wenn man es nicht vollumfänglich nutzen kann?

Naja, definiere „sauber“. Am Ende steht so oder so immer ein query. Schreib dir doch selbst eine Helper Method die dann nur mit den arguments für Key und Value callst.
Du kannst natürlich auch ORM und die Entities nutzen, wenn du dich vor SQL scheust:
 

$elementRepository = Shopware()->Models()->getRepository(‚Shopware\Models\Config\Element‘);
$valueRepository   = Shopware()->Models()->getRepository(‚Shopware\Models\Config\Value‘);

$element = $elementRepository->findOneBy([‚name‘ => $name]);
$shop = Shopware()->Models()->getRepository(‚Shopware\Models\Shop\Shop‘)->getActiveDefault();
$valueModel = $valueRepository->findOneBy([‚shop‘ => $shop, ‚element‘ => $element]);

if (!$valueModel) {
      $valueModel = new Shopware\Models\Config\Value();
}

$valueModel->setElement($element);
$valueModel->setShop($shop);
$valueModel->setValue($value);
Shopware()->Models()->persist($valueModel);
Shopware()->Models()->flush($valueModel);

1 „Gefällt mir“

Off-Topic:

@d.coder schrieb:

Naja, definiere „sauber“. Am Ende steht so oder so immer ein query. Schreib dir doch selbst eine Helper Method die dann nur mit den arguments für Key und Value callst.

Gasp „Wieso den OOP wenns am Schluss eh Bytecode ist“. Das ist jetzt vielleicht etwas überspitzt aber im Prinzip kann man das übertragen. Man sollte niemals direkt die Shopware Datenbank modifizieren. Es gibt hier keine Garantie, dass sich die Struktur nicht mal ändern und dein Plugin nicht mehr funktioniert. Nutzt du stattdessen saubere Helfer Klassen/Funktionen sieht das anders aus. Hier wirst du frühzeitig mit dem Deprecaed Annotierung vorgewarnt und kannst frühzeitig reagieren. Bei einem direkten Eingriff hast du gar keine Garantie, dass dein Plugin funktioniert. Ganz schlechte Einstellung meiner Meinung nach.

On-Topic:
Es geht noch etwas eleganter: Wenn du sowieso Zugriff auf das Plugin Form hast (nicht Config) kannst du dir einfach die Elemente holen:

Form();

  // Name des Elements wie du das Element bei
  // $form->setElement("name des elements")
  // genannt hast
  $element = $form->getElement("name des elements");

  // Direkt den Defaultwert ändern:
  $element->setValue("Neuer Wert");
  Shopware()->Models()->persist($element);

  // Liegt der Scope nicht auf Shop (sprich das Feld gilt für alle Subshops)
  // kannst du direkt zum Speichern springen

  // holt alle Werte der Subshops
  $values = $element->getValues();
  foreach ($values as $value) {
    $value->setValue("Neuer Wert");
    Shopware()->Models()->persist($value);
  }

  // speichern
  Shopware()->Models()->flush();
}

Code nicht getestet. 

Viele Grüße

1 „Gefällt mir“

Vielen Dank für Eure Hilfe!

Der Lösung von simkli habe ich den Vorzug gegeben, da er der für mich “sauberere” Weg ist.

Hinweis: In simkli’s Code muss bei folgender Zeile aus ->Models-> ein ->Models()-> werden

Models()->persist($element);

?>