Plugin prüfen / Plugin Tutorial

Hallo zusammen,
Unser Shop: V 6.4.18.1

wir wollen gerade ein Plugin erstellen um div. informationen aus der DB auszulesen und im Frontend wieder auszugeben.
Leider klappt das nicht so ganz, wie wir uns das vorstellen.
Status ist mittlerweile so:
Sobald wir das Plugin aktivieren, bleibt der Shop beim aufruf weiss.

Nun eine Frage:
Gibt es eine Möglichkeit, das Plugin auf Fehler zu debuggen?
oder eine Art Testtool?
Gibt es gute Tuts, welche man anwenden kann?

vielen Dank im Voraus für eure Hilfe.

Im error Log von PHP sollte sich eigentlich immer etwas finden lassen.

Ansonsten in .env auf von prod auf dev um den Symfony Debugger zu sehen (nicht im Live-System machen!).

1 „Gefällt mir“

Alternativ geht sicher auch print_r() ganz am Anfang

Hat mittlerweile funktioniert.

Leider funkioniert das gewünschte Auslesen der Daten nicht.
Wir versuchen die Lànder aus der DB auszulesen und grundsätzlich mal per dump() auszugeben.
Die Route funktioniert und kann per console debug:route aufgelöst werden.

das ist der inhalt der Dateien:
base.html.twig

{# file to extend #}
{% sw_extends '@Storefront/storefront/base.html.twig' %}

{% block base_script_router %}
    {{ parent() }}
    <script>
        window.router['widgets.fs.fstopbar.addVars'] = '{{ absolute_url(path('widgets.fs.fstopbar.addVars')) }}';
    </script>
{% endblock %}

routes.xml

<?xml version="1.0" encoding="UTF-8" ?>
<routes xmlns="http://symfony.com/schema/routing"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://symfony.com/schema/routing
        https://symfony.com/schema/routing/routing-1.0.xsd">
    <import resource="../../**/Storefront/Controller/*Controller.php" type="annotation" />
</routes>

die controller.php

<?php declare(strict_types=1);

namespace Fs\Storefront\Controller;

use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\Validation\DataBag\RequestDataBag;
use Shopware\Core\System\Country\CountryCollection;
use Shopware\Core\System\Country\SalesChannel\AbstractCountryRoute;
use Shopware\Core\System\SalesChannel\SalesChannel\SalesChannelContextSwitcher;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Shopware\Core\System\SystemConfig\SystemConfigService;
use Shopware\Storefront\Controller\StorefrontController;
use Shopware\Storefront\Pagelet\Header\HeaderPageletLoaderInterface;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Routing\Annotation\Route;
use Shopware\Core\Framework\Routing\Annotation\RouteScope;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

/**
 * @RouteScope(scopes={"storefront"})
 */

class FsTopbarController extends StorefrontController
{

    private SystemConfigService $systemConfigService;
    private AbstractCountryRoute $countryRoute;
    private SessionInterface $session;
    private HeaderPageletLoaderInterface $headerLoader;
    private SalesChannelContextSwitcher $contextSwitcher;

    public function __construct(
        SystemConfigService $systemConfigService,
        AbstractCountryRoute $countryRoute,
        SessionInterface $session,
        HeaderPageletLoaderInterface $headerLoader,
        SalesChannelContextSwitcher $contextSwitcher
    ) {
        $this->systemConfigService = $systemConfigService;
        $this->countryRoute = $countryRoute;
        $this->session = $session;
        $this->headerLoader = $headerLoader;
        $this->contextSwitcher = $contextSwitcher;
    }


    /**
     * ...
     *
     * 
     * @Route("/widgets/fs/fstopbar/addVars",
     *     name="widgets.fs.fstopbar.addVars",
     *     options={"seo"=false},
     *     methods={"GET"},
     *     defaults={"XmlHttpRequest"=true}
     * )
     *
     * @param Request $request
     * @param Context $context
     * @param SalesChannelContext $salesChannelContext
     *
     * @return Response
     */
    public function addVars(Request $request, Context $context, SalesChannelContext $salesChannelContext): Response
    {   
        return $this->renderStorefront('@Storefront/storefront/layout/header/top-bar.html.twig', ['page' => [
            'countries' => $this->getCountries($salesChannelContext)
        ]]);
    }

    /**
     * ...
     *
     * @Route("/widgets/fs/fstopbar/getCountries",
     *     name="widgets.fs.fstopbar.getCountries",
     *     options={"seo"=false},
     *     methods={"GET"},
     *     defaults={"XmlHttpRequest"=true}
     * )
     * 
     * @param SalesChannelContext $context
     *
     * @return CountryCollection
     */
    public function getCountries(SalesChannelContext $context): CountryCollection
    {
        $countries = $this->countryRoute->load(new Request(), new Criteria(), $context)->getCountries();
        $countries->sortByPositionAndName();
        return $countries;
    }
}

Kann uns hier jemand helfen, oder gibt es einen anderen Lösungsansatz?

Ich vermute, dass hier das Problem liegt, denn die „einfachen“ Anführungszeichen treten innerhalb der einfachen Anführungszeichen noch einmal auf, ich würde stattdessen probieren:

    window.router['widgets.fs.fstopbar.addVars'] = '{{ absolute_url(path("widgets.fs.fstopbar.addVars")) }}';

Viel Erfolg!

Hallo Florian,

vielen Dank für die Antwort. Leider hat dies nicht geholfen.

Was genau ist denn das Problem? Funktioniert denn der folgende Aufruf ?

ja der funktioniert.
Wenn wir es direkt aufrufen, dann wird mir der Dump angezeigt,
Aber im Shop selbst, zeigt es mir beim Dump „null“ an.

Wie rufst du die URL im Shop auf?

Ich denke, dass absolute_url nicht nötig ist. path sollte ausreichen im base.html.twig.

ich glaub, da liegt das problem.
der aufruf sollte normalerweise über js erfolgen.

Ich kenne deine Anforderung nicht.
Die URL sollte ganz normal über ein JS mit einem HTTP Client angesprochen werden.

Möchtest du die Länder im Template auf einer Seite ausgeben, so sollte ein Subscriber die Lösung sein. Im Subscriber kannst du die Länder laden und der Page z. B. als Extension zuweisen.

main.js

// import
import PluginManager from 'src/plugin-system/plugin.manager';
import FsTopbar from './plugin/fs/fstopbar/fs-topbar.plugin';

// register plugin
PluginManager.register(
    'FsTopbar',
    FsTopbar,
    'body'
);

fs-topbar.plugin.js

// import
import Plugin from 'src/plugin-system/plugin.class';
import HttpClient from 'src/service/http-client.service';

export default class FsTopbar extends Plugin { 
    // plugin configuration
    static options = {
        addVarsUrl: ''
    };

    // on init
    init() {
        // get this
        const me = this;

        // set urls
        this.options.addVarsUrl = window.router['widgets.fs.fstopbar.addVars'];
        
        // create http client
        this._httpClient = new HttpClient(window.accessKey, window.contextToken);

        // stop current http client
        this._httpClient.abort();

        // ...
        this._httpClient.get(this.options.addVarsUrl, '');
    }
}

das sind die beiden JS …
Grundsätzlich will ich erstmal den Grundstep verstehen mit Daten auslesen und ins Twig einbinden.
Final soll in der Topbar ein Dropdown eingebunden werden, wo Lieferland, Sprache und Währung eingestellt werden kann.

der HttpClient Konstruktor hat keine Paramter. Weiß nicht, ob das zu Fehlern führen kann.

Ansonsten sieht meiner Meonung nach alles in Ordnung aus, auch wenn dem Get kein Callback Funktion übergeben wurde.

Sicher, dass dein Controller beim Seitenaufruf nicht angesprochen wird (siehe Browser Console)?

Storefront hast du gebaut?

Wird dein gebautes JS im Frontend geladen ( siehe all.js )?

in der all.js is nix drin.

Storefront hast du gebaut? Über bin/build-storefront.sh?

Wenn dein JS weiterhin nicht in der all.js angezeigt wird, versuch Mal noch den window.PluginManager zu verwenden, um dein JS/Plugin zu registrieren.