Plugin Update -> neue Custom Fields mit upsert-Methode erscheinen erst beim zweiten Update Durchlauf

Hallo Community,

bei einem Plugin Update sollten per upsert-Methode zu bestehenden Custom Fields weitere hinzugefügt werden. Jedoch werden die neuen Custom Fields nur angelegt, wenn das Update „manuell“ durchgeführt wird, also durch manuelles Hochladen der Zip-Datei und über das Kontext-Menü.

In der Update-Methode des Plugins prüfen wir kurz die Version ab und fügen dann mit upsert die neuen Custom Fields an. Bei eigenen Tests und in den Demoshops hat das zuverlässig funktioniert.

public function update(UpdateContext $context): void
{
    if (version_compare($context->getCurrentPluginVersion(), '1.0.1', '<')) {
        //upsert der neuen Custom Fields
    }
}

Nun bekommen wir Meldungen, dass die neuen Custom Fields beim Update nicht angelegt werden.

Als Lösung lassen wir dann das Update noch einmal durchlaufen, indem wir in der composer.json kurzerhand die Versionsnummer wieder eine Version heruntersetzen und danach wieder hochsetzen - dann das Update über die Administration neu starten. Wir ändern also nichts am Code.

Danach sind die neuen Custom Fields vorhanden.

Bei eigenen Tests bei Updates, Neuinstallationen usw. durch manuell hochgeladene Plugins konnten wir das Problem bisher gar nicht reproduzieren.

Hat jemand eine Idee?

Nach weiteren Tests:
Es liegt nicht an der Abfrage mit version_compare. Ich vermute, dass es mit der upsert-Methode zusammenhängt. Leider lässt sich das Problem schwer nachstellen, da zum Reproduzieren das Update über das automatische Update eines mit dem Store verknüpften Shops gemacht werden muss.

Manuelles Update: :white_check_mark: funktioniert immer
Einstellungen > Meine Plugins
… dann über den Button „Plugin hochladen“ das Update hochladen
… dann über das Konext-Menü > Update auf x.x.x klicken
Bildschirmfoto 2021-03-18 um 18.12.14

Automatisches Update: :x: funktioniert erst beim zweiten mal
Einstellungen > Updates auf Aktualisieren drücken

Erst nachdem in der composer.json die Version einmal zurückgestellt und wieder hochgesetzt wurde und erneut auf „Aktualisieren“ gedrückt wurde, werden die neuen Custom Fields angelegt.

Bildschirmfoto 2021-03-18 um 18.12.27

Ich habe weiter getestet und den Code vereinfacht, um mögliche Fehlerquellen auszuschließen.

Es ist schwierig das zu testen, da es ja nur mit einem Plugin nachgestellt werden kann, welches über den Store / Account aktualisiert wird, denn bei manuellen Updates klappt es.

Anbei der Code ein wenig vereinfacht. Per upsert-Befehl soll also ein Feld aktualisiert oder auch angelegt werden:

<?php declare(strict_types=1);

namespace foo\BarFoo;

use Shopware\Core\Content\Category\CategoryDefinition;
use Shopware\Storefront\Framework\ThemeInterface;
use Shopware\Core\Framework\Plugin;
use Shopware\Core\Framework\Plugin\Context\InstallContext;
use Shopware\Core\Framework\Plugin\Context\UpdateContext;
use Shopware\Core\Framework\Context;

class fooBarFoo extends Plugin implements ThemeInterface
{
    public function getThemeConfigPath(): string
    {
        return 'theme.json';
    }

    public function install(InstallContext $installContext): void
    {
        parent::install($installContext);
    }

    public function update(UpdateContext $updateContext): void
    {
        parent::update($updateContext);
        $this->setupCustomFields($updateContext->getContext());
    }

    public function setupCustomFields(Context $context): void
    {
        $customFieldSetRepository = $this->container->get('custom_field_set.repository');

        $relationCategory = [
            'id' => 'bc1f032c888911eb8dcd0242ac130003',
            'entityName' =>  $this->container->get(CategoryDefinition::class)->getEntityName()
        ];

        $customFields = [
            [
                'id' => 'bc1f0570888911eb8dcd0242ac130003',
                'name' => 'foo_bar_field',
                'type' => 'CustomFieldTypes::SELECT',
                'config' => [
                    'customFieldPosition' => 10,
                    'componentName' => 'sw-single-select',
                    'label' => [
                        'en-GB' => 'Fooo',
                        'de-DE' => 'Fooo',
                    ],
                    'options' => [
                        [
                            'value' => 'foo',
                            'label' => [
                                'en-GB' => 'Foo',
                                'de-DE' => 'Foo',
                            ]
                        ],
                        [
                            'value' => 'bar',
                            'label' => [
                                'en-GB' => 'Bar',
                                'de-DE' => 'Bar',
                            ]
                        ],
                    ]
                ],
            ],
        ];

        $customFieldSets = [
            [
                'id' => 'bc1f0714888911eb8dcd0242ac130003',
                'name' => 'foo_bar_set',
                'config' => [
                    'label' => [
                        'en-GB' => 'Foo',
                        'de-DE' => 'Foo',
                    ]
                ],
                'customFields' => $customFields,
                'relations' => [$relationCategory]
            ],
        ];


        $customFieldSetRepository->upsert($customFieldSets, $context);
    }
}

Resultat: Das Custom Field erscheint nicht, bzw. wird nicht verändert
Erwartetes Resultat: Das Custom Field wird erstellt, wenn nicht vorhanden. Es wird aktualisiert, wenn vorhanden.

Das Problem kann nur reproduziert werden, wenn über die Administration das Update per „Aktualisieren“-Button angestoßen wird. Bei einem manuellen Update, durch Hochladen des Plugins per FTP oder Plugin Hochladen-Button, funktioniert es.

Wie kann das sein? Vor allem, warum funktioniert es auf einmal, wenn das selbe Update nur durch Zurückstellen der Plugin-Version über „Aktualisieren“ erneut durchgeführt wird?
Liegt der Fehler bei uns oder im Core?
Kann jemand was erkennen?

@Michael_Telgmann irgendeine Idee?

Hallo zenit,

hast du die Möglichkeit das Problem in einer Shopware 6.4 RC Umgebung zu testen?
Die Ursache für das Problem könnte sein, dass bisher das Herunterladen des Updates und die Ausführung des Updates in einem Request passiert sind. Dadurch wurden eventuelle Änderungen die beim Herunterladen des Updates mitgeliefert werden, bei der Update Routine noch gar nicht berücksichtigt.

Dies hat sich in Shopware 6.4 geändert und es wird zuerst das Update heruntergeladen und dann in einem neuen Request das Update an sich ausgeführt. Dadurch sollte der Fehler nicht mehr auftreten.

Für diese Ursache spricht, dass ein Manuelles Update ohne Probleme funktioniert.

Viele Grüße aus Schöppingen

Michael Telgmann

Hallo Michael Telgmann,

vielen Dank für die Rückmeldung. Das könnte tatsächlich eine Ursache sein.

Die 6.4.0.0 RC habe ich in meiner Entwicklungsumgebung. Die lokale Umgebung ist jedoch nicht mit einem Account verknüpft und kann auch keine Updates über den Store beziehen.

Wird unter Extensions denn weiterhin zwischen „lokalem Update“ und „Store Update“ unterschieden?

Viele Grüße, David

Hallo David,

das kann ich dir jetzt leider nicht sicher beantworten. Aber ich gehe davon aus, dass es so bleibt, da es ja doch zwei unterschiedliche Use-Cases sind.

Viele Grüße aus Schöppingen

Michael Telgmann