Files
michaelschiemer/docs/refactoring/placeholder-protection-refactoring.md
2025-11-24 21:28:25 +01:00

4.5 KiB

Placeholder Protection Refactoring

Problem

Die Navigation-Links enthalten PLACEHOLDER_0___ statt echte URLs. Der Parser schützt Placeholders während des Attribut-Parsings, aber sie werden nicht korrekt zurückgesetzt oder verarbeitet.

Root Cause Analysis

  1. HtmlParser::parseAttributes schützt Placeholders (___PLACEHOLDER_X___) während des Regex-Parsings
  2. Placeholders werden zurückgesetzt, bevor setAttribute aufgerufen wird
  3. Aber der ForTransformer findet sie nicht, weil:
    • Die Attribute werden HTML-encoded gespeichert
    • Der ForTransformer dekodiert sie mit html_entity_decode
    • Aber die Placeholders könnten bereits verarbeitet worden sein

Refactoring-Vorschlag

Option 1: Placeholder-Schutz entfernen (Einfachste Lösung)

Problem: Der Regex für Attribut-Parsing bricht bei geschachtelten Anführungszeichen in Placeholders.

Lösung: Statt Placeholders zu schützen, den Regex robuster machen, um geschachtelte Anführungszeichen zu handhaben.

Vorteile:

  • Einfacher Code
  • Keine Placeholder-Wiederherstellung nötig
  • Weniger Fehlerquellen

Nachteile:

  • Komplexerer Regex erforderlich

Option 2: Placeholder-Schutz verbessern (Empfohlen)

Problem: Der aktuelle Schutz-Mechanismus ist fehleranfällig.

Lösung:

  1. Placeholders mit eindeutigen IDs schützen (bereits implementiert)
  2. Placeholders IMMER zurückersetzen, auch wenn sie nicht im Attribut-Wert gefunden werden
  3. Validierung hinzufügen, um sicherzustellen, dass alle geschützten Placeholders zurückgesetzt wurden

Vorteile:

  • Robuster
  • Bessere Fehlerbehandlung
  • Validierung verhindert Bugs

Nachteile:

  • Mehr Code-Komplexität

Option 3: Placeholder-Verarbeitung in ForTransformer verbessern

Problem: Der ForTransformer erkennt geschützte Placeholders nicht korrekt.

Lösung:

  1. Geschützte Placeholders erkennen und verarbeiten
  2. Fallback-Mechanismus, falls HtmlParser sie nicht zurückgesetzt hat
  3. Besseres Logging für Debugging

Vorteile:

  • Funktioniert auch wenn HtmlParser fehlschlägt
  • Bessere Fehlerbehandlung

Nachteile:

  • Dupliziert Logik zwischen HtmlParser und ForTransformer

Empfohlene Lösung

Kombination aus Option 2 und 3:

  1. HtmlParser verbessern: Validierung hinzufügen, um sicherzustellen, dass alle geschützten Placeholders zurückgesetzt wurden
  2. ForTransformer verbessern: Fallback-Mechanismus für geschützte Placeholders
  3. Besseres Logging: Umfassendes Logging für Debugging

Implementierung

Schritt 1: HtmlParser::parseAttributes verbessern

private function parseAttributes(ElementNode $element, string $attributesString): void
{
    // ... existing code ...
    
    // After restoring placeholders, validate that all were restored
    foreach ($placeholders as $key => $placeholder) {
        if (str_contains($value, $key)) {
            throw new \RuntimeException("Placeholder {$key} was not restored in attribute {$name}");
        }
    }
}

Schritt 2: ForTransformer::processPlaceholdersInAllNodes verbessern

// If we find protected placeholders, try to restore them from context
if (preg_match('/___PLACEHOLDER_(\d+)___/', $decodedValue, $matches)) {
    // This is a fallback - HtmlParser should have restored it
    // But if it didn't, we can't process it
    if (getenv('APP_DEBUG') === 'true') {
        error_log("ForTransformer::processPlaceholdersInAllNodes: CRITICAL - Found protected placeholder in attribute '{$attrName}': {$decodedValue}");
        error_log("ForTransformer::processPlaceholdersInAllNodes: This is a bug - HtmlParser should have restored it");
    }
    // Skip this attribute - it's malformed
    continue;
}

Schritt 3: Besseres Logging

// Add comprehensive logging at each step
if (getenv('APP_DEBUG') === 'true') {
    error_log("HtmlParser::parseAttributes: Processing attribute '{$name}'");
    error_log("HtmlParser::parseAttributes: Original value: " . substr($value, 0, 100));
    error_log("HtmlParser::parseAttributes: Protected placeholders: " . count($placeholders));
    error_log("HtmlParser::parseAttributes: Restored value: " . substr($value, 0, 100));
}

Testing

  1. Unit-Tests für HtmlParser::parseAttributes
  2. Unit-Tests für ForTransformer::processPlaceholdersInAllNodes
  3. Integration-Tests für den gesamten Flow
  4. Edge-Case-Tests für geschachtelte Anführungszeichen

Migration

  • Keine Breaking Changes
  • Bestehende Templates funktionieren weiterhin
  • Neue Validierung verhindert zukünftige Bugs