JTL Shop 5 Plugin
Mit diversen Extensions
Das Plugin verbindet den JTL-Shop mit AUSGEZEICHNET.org:
ausgezeichnet_jtl5.zip auswählen und hochladen.xplugin_ausgezeichnet_jtl5_invites an (Migration Migration20260629000001). Das ist die Tracking-Tabelle für die automatische Einladung (siehe Abschnitt 2.4) – hier ist keine manuelle Aktion nötig.Alle Werte findest du im AUSGEZEICHNET.org Kundencenter:
| Feld | Bedeutung |
|---|---|
| Organisation-ID | Wird für die Widget-Script-URLs benötigt. Ohne diesen Wert werden keine Widgets geladen. |
| Kontonummer | Kundencenter → Kontonummer. Fließt in die Hash-Berechnung der Bewertungslinks ein. |
| Bewertungs-ID | Kundencenter → Bewertungs-ID. Ebenfalls Teil der Hash-Berechnung. |
| Bewertungs-URL | Basis-URL für personalisierte Bewertungslinks. Nur Schema+Host+Pfad eintragen, keine Query-Parameter – vorhandene werden automatisch entfernt. Muss https:// sein. |
| API-Schlüssel | Nötig für die automatische Einladungs-Funktion. Kann alternativ per Umgebungsvariable AUSGEZEICHNET_API_KEY gesetzt werden (überschreibt den Wert aus dem Backend – praktisch für getrennte Staging-/Live-Systeme). |
| Sprach-Override | Optional, z. B. de oder en. Leer lassen für automatische Erkennung aus der Shop-Sprache. |
Tab Tools und Setup öffnen (letzter Reiter des Plugins) → Abschnitt „Konfigurationsstatus“ zeigt für jedes Pflichtfeld ✓/✗. Erst wenn alle fünf Punkte grün sind, funktionieren Widgets, E-Mail-Links und automatische Einladungen vollständig.
Damit ist die Installation abgeschlossen. Die eigentliche Funktionskonfiguration erfolgt in den Tabs „Widgets“, „E-Mail Bewertungslink“ und „Automatische Einladung“ – siehe Betriebsanleitung.
Das Plugin hat 5 Admin-Tabs. Änderungen an Selectbox-/Text-Einstellungen wirken sofort, ohne dass der Shop-Cache manuell geleert werden muss.
| Einstellung | Beschreibung |
|---|---|
| Schwebendes Siegel/Badge | „Dynamic Seal“ und „Trust Badge“ schließen sich gegenseitig aus – nur eines aktivieren. |
| Review Modal / Review Collector (Split/Hero) / Review Slider / Review Carousel | Jeweils eigenständig aktivierbar. Erfordern ein Platzhalter-Element im Shop-Template (ID/Attribut laut AUSGEZEICHNET.org Dashboard) – ohne passenden Platzhalter erscheint nichts, obwohl das Skript geladen wird. |
| Produkt-Bewertungswidget | Zeigt Produktbewertungen. Auf jeder Produktseite fügt das Plugin den Container |
| Produkt-Widget Darstellungstyp | Badge / Hero / Horizontal → Attribut auorg-data-type. |
| Produkt-Widget automatisch einfügen | Standard „Ja“. Auf „Nein“ stellen, wenn der Container manuell (z. B. per OnPage-Composer-Portlet) gesetzt wird. Ein bereits vorhandener Container wird nie verdoppelt. |
| Produkt-Widget Einfügestelle (CSS-Selektor) | Der Container wird nach dem ersten passenden Element eingefügt. Standard .product-title (Produktname im NOVA-Template); nur bei eigenen Templates anpassen. |
| Review Collector (Legacy) | Nur auf ausdrückliche Empfehlung des AUSGEZEICHNET.org Supports aktivieren. |
| Ausgeschlossene Seiten | Eine URL-Teilzeichenkette pro Zeile (z. B. /bestellvorgang, /mein-konto, /warenkorb). Auf passenden Seiten werden keine Widgets geladen – die Einwilligungs-Checkbox (siehe 2.3) wird davon nicht beeinflusst und weiterhin angezeigt. |
Alle aktivierten Widget-Skripte werden pro Seitenaufruf einmal vor eingefügt (Hook HOOK_SMARTY_OUTPUTFILTER).
Fügt einen Bewertungsblock (Text + Button + optionales Siegel-Bild) in Transaktions-E-Mails ein. Es gibt zwei unabhängige Wege, das umzusetzen – einen davon wählen, nicht kombinieren:
a) Automatisch injizieren (empfohlen)
Im Tab Tools und Setup → Abschnitt „E-Mail Bewertungsblock – Auto-Setup“ → Button „▶ Bewertungsblock einfügen“. Das Plugin hängt dann an die ausgewählten E-Mail-Templates (temailvorlage) einen mit markierten Smarty-Snippet an, der die Bewertungs-URL bei jedem E-Mail-Versand individuell berechnet. Über „✕ Bewertungsblock entfernen“ lässt sich das wieder rückgängig machen. Die Tabelle in diesem Abschnitt zeigt, welche der drei Templates (Bestellbestätigung, Versandbestätigung, Rechnung) bereits injiziert sind.
b) Manuell im Template einbinden
In ein beliebiges E-Mail-Template einfügen:
{ausgezeichnet_email_block kBestellung=$oBestellung->kBestellung collmethod="pos"}
collmethod ist "pos" (Point of Sale, z. B. Bestellbestätigung/Rechnung) oder "af" (After Fulfillment, z. B. Versandbestätigung).
Steuerbar über die drei Selectboxen „In Bestellbestätigung/Versandbestätigung/Rechnungs-E-Mail einfügen“ (wirken nur auf Methode a), sowie Blocktext, Button-Beschriftung und optionale Siegel-Bild-URL (muss https:// sein).
Versendet automatisiert Bewertungseinladungen über die AUSGEZEICHNET.org Invite-API.
| Einstellung | Beschreibung |
|---|---|
| Automatische Einladung aktiviert | Hauptschalter. |
| Trigger: Nach Zahlung/Rechnung | Löst aus, wenn die Bestellung Status „In Bearbeitung“ (2) oder „Bezahlt“ (3) erhält. |
| Trigger: Nach Versand/Abschluss | Löst aus, wenn die Bestellung Status „Versandt“ (4) erhält. Sinnvoll bei digitalen Produkten oder wenn „In Bearbeitung“ übersprungen wird. |
| Verzögerung in Tagen (0–30) | Wartezeit, die AUSGEZEICHNET.org selbst einhält, bevor die Einladungs-E-Mail verschickt wird (z. B. 7 Tage, damit das Paket ankommen kann). |
| Collection Method | „After Fulfillment“ oder „Point of Sale“ – nur für die Shop-Bewertungseinladung relevant. |
| Shop-Bewertungseinladung senden | Eine Einladung pro Bestellung für die Gesamt-Shop-Bewertung. |
| Produkt-Bewertungseinladungen senden | Eine Einladung pro Bestellposition (SKU/Artikelnummer, Fallback: interne Artikel-ID). |
| Einwilligung erforderlich | Wenn aktiviert: Checkbox im Checkout, standardmäßig nicht vorangehakt (Opt-in). Wenn deaktiviert: alle Kunden gelten als eingewilligt. |
Beim Bestellabschluss (Hook HOOK_BESTELLABSCHLUSS_INC_BESTELLUNGINDB_ENDE) legt das Plugin pro Bestellung genau einen Datensatz in xplugin_ausgezeichnet_jtl5_invites an (E-Mail, Name, Einwilligung, Status). Beim Statuswechsel (Hook HOOK_BESTELLUNGEN_XML_BESTELLSTATUS) prüft das Plugin diesen Datensatz:
bConsent = 0 → Kunde hat nicht eingewilligt, keine Einladung.bSent = 1 → bereits gesendet, keine doppelte Einladung (auch bei mehrfachem Statuswechsel, z. B. hin- und zurückgesetzt).Erst wenn die API-Aufrufe erfolgreich waren, wird bSent = 1 und dGesendet gesetzt. Bei einem API-Fehler bleibt der Datensatz auf „nicht gesendet“ stehen und es gibt aktuell keinen automatischen Retry – ein erneuter Statuswechsel (z. B. manuell im Backend Status kurz zurück- und wieder vorsetzen) würde einen neuen Versuch auslösen.
Alle Formulare auf dieser Seite sind CSRF-geschützt (JTL-Admin-Token); bei „Sicherheitstoken ungültig“ die Seite neu laden und erneut versuchen (meist nach sehr langer Inaktivität der Backend-Session).
Shop::Container()->getLogService()) protokolliert, sichtbar unter Admin → System → Fehlerprotokoll/Logs. Log-Einträge sind mit dem Präfix [ausgezeichnet_jtl5] versehen.auorgProductRating suchen. Fehlt der Container, passt der CSS-Selektor nicht zum Template oder der Artikel hat keine Artikelnummer. Ist er vorhanden, aber leer, liegen bei AUSGEZEICHNET.org für diese SKU (noch) keine Bewertungen vor.bConsent)? Wurde schon versendet (bSent)? Log auf HTTP-Fehler der AUSGEZEICHNET.org API prüfen./bestellvorgang, /checkout) bzw. Smarty-Seitentyp erkannt; bei stark angepassten Checkout-Templates ggf. die CSS-Selektoren in OutputFilterHook::maybeInjectConsentCheckbox() anpassen.| Bereich | Problem | Fix |
|---|---|---|
Hooks/OutputFilterHook.php |
Das Produkt-Bewertungswidget lud nur product-rating.js, setzte aber keinen Container mit SKU – das Widget blieb unsichtbar, solange der Container nicht von Hand ins Template eingefügt wurde. |
Container wird auf Produktseiten automatisch mit cArtNr eingefügt; Skript nur noch auf Seiten mit Container, offizielle URL www.ausgezeichnet.org/widgets/…/product-rating.js?lang=… mit defer |
Services/Config.php |
Einstellung „Produkt-Widget Darstellungstyp“ wurde nie ausgewertet. | Wird als auorg-data-type übergeben |
info.xml |
– | Neue Einstellungen „automatisch einfügen“ und „Einfügestelle (CSS-Selektor)“ |
Version 1.0.2 ließ sich auf JTL-Shop 5.5–5.9 nicht installieren und hätte im Betrieb das Frontend lahmgelegt. Behoben wurde:
| Bereich | Problem | Fix |
|---|---|---|
info.xml |
MinShopVersion 550 / MaxShopVersion 599 werden von JTLs SemVer-Parser als 5.50.0 / 5.99.0 gelesen (die 3-stellige Kurzform ist MAJOR + 2-stellige MINOR). Der Shop meldete daher „kompatibel mit 5.50.0 – 5.99.0“ und brach die Installation mit SHOP_VERSION_COMPATIBILITY ab. |
Punktnotation 5.5.0 / 5.9.9 |
info.xml |
Plugin-Name enthielt . und &; JTLs Validator erlaubt nur [A-Za-z0-9_() -] → INVALID_NAME. Gleiches beim Tab „Tools & Setup“. |
Name → AUSGEZEICHNET-org_Shop-Product_Reviews, Tab → „Tools und Setup“ |
Migrations/ |
Migration implementierte JTL\Update\IMigration nicht. Der MigrationManager wirft dafür eine InvalidNamespaceException – die Tabelle wurde nie angelegt. |
implements IMigration + $author / $description |
Hooks/OutputFilterHook.php |
Typehints auf \phpQueryObject; die Klasse heißt seit Shop 5 JTL\phpQuery\phpQueryObject, ein globaler Alias existiert nicht → TypeError bei jedem Seitenaufruf im Frontend. |
Namespaced Import |
Hooks/OutputFilterHook.php |
->last() gibt es auf phpQueryObject nicht (__call() wirft); der Fallback für die Einwilligungs-Checkbox knallte, sobald #CustomerComment fehlte. |
:last-Pseudoselektor + Count-Guard |
Hooks/OutputFilterHook.php |
Checkout-Erkennung prüfte nSeitenTyp === 17 – das ist PAGE_VERGLEICHSLISTE, nicht der Checkout. |
PAGE_BESTELLVORGANG (11) |
Hooks/OrderStatusHook.php |
„Nach Versand“ prüfte Status 3 = BESTELLUNG_STATUS_BEZAHLT, nicht 4 = VERSANDT. |
Shop-Konstanten statt Magic Numbers; „nach Zahlung“ deckt jetzt 2 und 3 ab |
OrderStatusHook, OrderCompletedHook, tab_tools.php |
getSingleObject()/getObjects() wurden mit dem alten ReturnType-Argument aufgerufen. Aktuelle Signatur ist (string $stmt, array $params = []) → TypeError. |
ReturnType entfernt |
adminmenu/tab_tools.php |
Helfer waren globale Funktionen in einer Datei, die der PluginController per require (nicht require_once) einbindet → Redeclare-/Kollisionsrisiko; eigener CSRF-Nachbau statt JTL\Helpers\Form. |
Neue Klasse Services\AdminTools, CSRF über Form::getTokenInput() / Form::validateToken() |
Die Einstellungen und die Tracking-Tabelle sind unverändert – ein Update von 1.0.x erfordert keine Neukonfiguration.