← Code-Übersicht

ProzessDetailAction.php

Pfad: src/Infrastructure/Http/ProzessDetailAction.php

Ext: php

Größe: 3345 Bytes

Geändert: 2026-07-15 23:57:49+02

<?php
declare(strict_types=1);

namespace Demo\Infrastructure\Http;

use Demo\Application\Prozess\ZeigeProzess;
use Demo\Infrastructure\Content\MarkdownToHtml;
use Demo\Infrastructure\Flow\FlussLayout;
use Demo\Infrastructure\Flow\SvgFluss;

/**
 * Treibender Adapter: zeigt /prozesse/{slug} read-only mit SVG-Fluss und Schritt-Karten.
 */
final class ProzessDetailAction
{
    /** @var ZeigeProzess Anwendungsfall. */
    private ZeigeProzess $zeige;

    /** @var MarkdownToHtml Markdown-Renderer. */
    private MarkdownToHtml $markdown;

    /** @var FlussLayout Layout-Berechnung. */
    private FlussLayout $layout;

    /** @var SvgFluss SVG-Renderer. */
    private SvgFluss $svg;

    /** @var TemplateRenderer Template-Renderer. */
    private TemplateRenderer $view;

    /** @var Navigation Hauptnavigation. */
    private Navigation $nav;

    /**
     * @param ZeigeProzess     $zeige    Anwendungsfall.
     * @param MarkdownToHtml   $markdown Markdown-Renderer.
     * @param FlussLayout      $layout   Layout-Berechnung.
     * @param SvgFluss         $svg      SVG-Renderer.
     * @param TemplateRenderer $view     Renderer.
     * @param Navigation       $nav      Navigation.
     */
    public function __construct(
        ZeigeProzess $zeige,
        MarkdownToHtml $markdown,
        FlussLayout $layout,
        SvgFluss $svg,
        TemplateRenderer $view,
        Navigation $nav
    ) {
        $this->zeige = $zeige;
        $this->markdown = $markdown;
        $this->layout = $layout;
        $this->svg = $svg;
        $this->view = $view;
        $this->nav = $nav;
    }

    /**
     * Baut die Detailseite oder liefert 404.
     *
     * @param array<string,string> $params Routen-Parameter (slug).
     * @return Response HTML-Antwort.
     */
    public function __invoke(array $params): Response
    {
        $detail = $this->zeige->execute($params['slug'] ?? '');
        if ($detail === null) {
            return new Response(404, 'text/plain; charset=UTF-8', 'Nicht gefunden');
        }
        $knoten = [];
        foreach ($detail->schritte as $schritt) {
            $knoten[] = $schritt->id;
        }
        $kanten = [];
        foreach ($detail->kanten as $kante) {
            $kanten[] = [$kante->vorgaengerId, $kante->schrittId];
        }
        $layout = $this->layout->berechne($knoten, $kanten);

        $schritte = $detail->schritte;
        $pos = $layout['pos'];
        usort($schritte, static function ($a, $b) use ($pos): int {
            return [$pos[$a->id]['rang'] ?? 0, $a->id] <=> [$pos[$b->id]['rang'] ?? 0, $b->id];
        });
        $schrittHtml = [];
        foreach ($detail->schritte as $schritt) {
            $schrittHtml[$schritt->id] = $this->markdown->render($schritt->beschreibung);
        }

        $html = $this->view->render('layout', [
            'inner' => 'prozess-detail',
            'titel' => $detail->prozess->titel,
            'aktiv' => '/prozesse',
            'nav' => $this->nav->items(),
            'detail' => $detail,
            'svg' => $this->svg->render($detail, $layout),
            'kopfHtml' => $this->markdown->render($detail->prozess->beschreibung),
            'schritte' => $schritte,
            'schrittHtml' => $schrittHtml,
        ]);

        return new Response(200, 'text/html; charset=UTF-8', $html);
    }
}