Neu In JTL-Shop 5.8.2 tritt beim Bearbeiten einer per „In Linkgruppe kopieren“ erzeugten Referenzseite reproduzierbar ein HTTP-500-Fehler auf

TDS2018

Sehr aktives Mitglied
25. Oktober 2018
646
106
Fehlerbeschreibung:
In JTL-Shop 5.8.2 tritt beim Bearbeiten einer per „In Linkgruppe kopieren“ erzeugten Referenzseite reproduzierbar ein HTTP-500-Fehler auf.

Ausgangssituation:
  • Es existiert eine normale CMS-Seite, z. B. kLink 378.
  • Diese Seite wird über „In Linkgruppe kopieren“ in eine weitere Linkgruppe kopiert.
  • JTL legt dafür korrekt einen Referenz-Link an, z. B.:
    • kLink = 469
    • nLinkart = 36
    • reference = 378
  • Der Referenz-Link besitzt dabei keine eigenen Einträge in tlinksprache.
Sobald man im Backend diese Referenz über „Bearbeiten“ öffnet, schlägt der Request

POST /admin/links
mit HTTP 500 fehl.

Im Apache-/PHP-Log erscheint dabei mehrfach:

PHP Warning: Attempt to read property "cISO" on null
in /var/www/jtlshop/includes/src/Link/Link.php on line 538
Die betroffene Stelle ist:

public function getURL(?int $idx = null): string
{
return $this->urls[$idx ?? $this->currentLanguageID]
?? '/?s=' . $this->getID()
. '&lang=' . Shop::Lang()->getIsoFromLangID($idx ?? $this->currentLanguageID)->cISO;
}
Ursache:
Die Referenz wird in Link::load() zunächst mit ihrer eigenen kLink geladen:

$links = $this->fetchLinkData($id);
fetchLinkData() verwendet jedoch einen INNER JOIN auf tlinksprache:

JOIN tlinksprache loc
ON tlink.kLink = loc.kLink
Da der Referenz-Link selbst keine Sprachdatensätze besitzt, kann er auf diesem Weg nicht vollständig geladen werden.

Erst danach versucht der Code, über das Feld reference auf die eigentliche Seite aufzulösen. Zu diesem Zeitpunkt ist es bereits zu spät.

Auswirkung:
  • Referenzlinks können im Backend nicht bearbeitet werden.
  • Der Request endet mit HTTP 500.
  • Die Referenz selbst kann im Frontend dennoch funktionieren.
  • Das Problem ist unabhängig vom verwendeten Child-Template.
  • Die Sprachkonfiguration des Shops war korrekt (ger, eng, fre).
Workaround / funktionierende Korrektur:
Die Referenz muss vor dem eigentlichen Laden der Sprach-/Linkdaten aufgelöst werden.

Statt:
$this->id = $id;
$links = $this->fetchLinkData($id);
funktioniert folgende Reihenfolge:

$this->id = $id;

$realID = $this->getRealID($id);
$links = $this->fetchLinkData($realID);

if (\count($links) === 0) {
throw new InvalidArgumentException(
'Provided link id ' . $this->id . ' not found.'
);
}

if ($realID !== $id) {
foreach ($links as $link) {
$link->reference = $realID;
}
}
Danach lässt sich die Referenzseite im Backend ohne HTTP 500 bearbeiten.

Getestet mit:
  • JTL-Shop 5.8.2
  • Referenz-Linktyp nLinkart = 36
  • Mehrsprachiger Shop: Deutsch, Englisch, Französisch
 
  • Gefällt mir
Reaktionen: sh-si

sh-si

Aktives Mitglied
10. Januar 2014
11
2
Danke für die saubere Analyse – wir können das bestätigen, und zwar mit einer deutlich schwerwiegenderen Auswirkung: Dieselbe Ursache kann den kompletten Shop lahmlegen.

Umgebung: JTL-Shop 5.8.2, Child-Template auf Basis NOVA

Fall 1 – Referenz bearbeiten (wie oben beschrieben):
Klick auf „Bearbeiten“ bei einer bestehenden Referenz (kLink 110, nLinkart 36, reference 68) → HTTP 500:

Code:
PHP Fatal error: Uncaught InvalidArgumentException: Provided link id 110 not found.
in includes/src/Link/Link.php:159
#0 includes/src/Router/Controller/Backend/LinkController.php(731): JTL\Link\Link->load()
#1 includes/src/Router/Controller/Backend/LinkController.php(70): JTL\Router\Controller\Backend\LinkController->actionEditLink()

Fall 2 – Referenz als Unterseite → Totalausfall Frontend:
Eine Seite (kLink 191, Linkgruppe 1) wurde unter eine Seite aus einer anderen Linkgruppe (kLink 68, Linkgruppe 4) eingeordnet. Der Shop hat dafür automatisch Referenzen angelegt, u. a. kLink 193 (nLinkart 36, reference 191, kVaterLink 68) – also eine Referenz als Unterseite.

Ab diesem Speichervorgang lieferte JEDE Frontendseite HTTP 500, ebenso /admin/links und /admin/orders. Cache leeren half nicht:

Code:
PHP Fatal error: Uncaught InvalidArgumentException: Provided link id 193 not found.
in includes/src/Link/Link.php:159
#0 includes/src/Link/Link.php(1128): JTL\Link\Link->load()
#1 includes/src/Link/Link.php(315): JTL\Link\Link->buildChildLinks()
#2 includes/src/Link/LinkList.php(94): JTL\Link\Link->map()
...
#7 includes/src/Link/LinkGroupList.php(66): JTL\Link\LinkGroupList->loadDefaultGroups()
#8 includes/src/Services/JTL/LinkService.php(96): JTL\Link\LinkGroupList->loadAll()

buildChildLinks() lädt jede Unterseite per Link::load() – mit genau dem oben beschriebenen INNER JOIN auf tlinksprache. Da der LinkService bei jedem Request initialisiert wird, reicht eine einzige Referenz als Unterseite, um den gesamten Shop abzuschießen.

Workaround: Referenz-Link 193 per SQL entfernt (tlink, tlinkgroupassociations, tseo), Cache geleert → Shop läuft wieder.

Ergänzende Punkte für JTL:
- Laut Guide bietet „Unter Link einordnen“ nur Seiten derselben Linkgruppe an. Trotzdem ließ sich eine Oberseite aus einer anderen Gruppe setzen, wodurch die Referenz als Unterseite entstand. Das sollte entweder unterbunden oder sauber unterstützt werden.
- Ein einzelner nicht ladbarer Link sollte nicht den gesamten LinkService abbrechen lassen, sondern übersprungen und geloggt werden.

Der vorgeschlagene Fix (Referenz per getRealID() vor fetchLinkData() auflösen) sollte beide Fälle beheben, da beide über Link::load() laufen.

Gibt es dazu schon ein Issue im Tracker?
 

TDS2018

Sehr aktives Mitglied
25. Oktober 2018
646
106
@sh-si
Könntest Du dafür bitte ein Ticket aufmachen? Ich weiß nicht, ob ich es aus meinem Standardpaket aus machen kann. Irgendwann hat JTL die Praxis geändert und das Ticketsystem an einen Wartungsvertrag gekoppelt. Ich weiß nicht, ob das noch der Fall ist. Oder wenn Du mir einen Link senden kannst, wo ich das Problem eintragen kann, werde ich es gerne machen. Danke.
 

Ähnliche Themen