ContractController.php

Code Hygiene Score: 100

Keine Issues gefunden.

Dependencies 4

Klassen 1

Funktionen 9

Versionen 18

Code

<?php

declare(strict_types=1);

namespace Controller;

// @responsibility: HTTP-Endpunkte für Contract-Management (YAML-basierte Konfigurationen)

use Domain\Repository\ContractRepositoryInterface;
use Framework\Controller;

class ContractController extends Controller
{
    private ContractRepositoryInterface $repository;

    public function __construct(ContractRepositoryInterface $repository)
    {
        $this->repository = $repository;
    }

    /**
     * GET /contracts
     */
    public function index(): void
    {
        $filters = [];
        $status = $this->getString('status');
        if ($status !== '') {
            $filters['status'] = $status;
        }

        $contracts = $this->repository->findAll($filters);
        $stats = $this->repository->getStatistics();

        $this->view('contracts.index', [
            'title' => 'Contracts',
            'contracts' => $contracts,
            'stats' => $stats,
            'currentStatus' => $status,
        ]);
    }

    /**
     * GET /contracts/new
     */
    public function contractNew(): void
    {
        $this->view('contracts.new', [
            'title' => 'Neuer Contract',
        ]);
    }

    /**
     * POST /contracts
     */
    public function store(): void
    {
        $this->requireCsrf();

        $isHtmx = $this->isHtmxRequest();
        $name = trim($_POST['name'] ?? '');
        $version = trim($_POST['version'] ?? '1.0');
        $yamlContent = $_POST['yaml_content'] ?? '';
        $scopeDescription = trim($_POST['scope_description'] ?? '');
        $status = $_POST['status'] ?? 'active';

        if ($name === '' || $yamlContent === '') {
            if ($isHtmx) {
                $this->htmxError('Name und YAML-Inhalt sind erforderlich.');

                return;
            }
            $_SESSION['error'] = 'Name und YAML-Inhalt sind erforderlich.';
            $this->redirect('/contracts/new');
        }

        // YAML-Syntax validieren
        try {
            yaml_parse($yamlContent);
        } catch (\Exception $e) {
            if ($isHtmx) {
                $this->htmxError('Ungültige YAML-Syntax: ' . $e->getMessage());

                return;
            }
            $_SESSION['error'] = 'Ungültige YAML-Syntax: ' . $e->getMessage();
            $this->redirect('/contracts/new');
        }

        $contractId = $this->repository->create([
            'name' => $name,
            'version' => $version,
            'yaml_content' => $yamlContent,
            'scope_description' => $scopeDescription,
            'status' => $status,
        ]);

        if ($isHtmx) {
            $this->htmxRedirect('/contracts/' . $contractId);

            return;
        }

        $_SESSION['success'] = 'Contract erfolgreich erstellt.';
        $this->redirect('/contracts/' . $contractId);
    }

    /**
     * GET /contracts/{id}
     */
    public function show(string $id): void
    {
        $contract = $this->repository->findById((int) $id);

        if ($contract === null) {
            $this->notFound('Contract nicht gefunden');
        }

        $history = $this->repository->getHistory((int) $id);
        $validations = $this->repository->getValidations((int) $id, 10);

        $this->view('contracts.show', [
            'title' => $contract['name'],
            'contract' => $contract,
            'history' => $history,
            'validations' => $validations,
        ]);
    }

    /**
     * GET /contracts/{id}/edit
     */
    public function edit(string $id): void
    {
        $contract = $this->repository->findById((int) $id);

        if ($contract === null) {
            $this->notFound('Contract nicht gefunden');
        }

        $this->view('contracts.edit', [
            'title' => 'Contract bearbeiten: ' . $contract['name'],
            'contract' => $contract,
        ]);
    }

    /**
     * POST /contracts/{id}
     */
    public function update(string $id): void
    {
        $this->requireCsrf();

        $isHtmx = $this->isHtmxRequest();
        $contract = $this->repository->findById((int) $id);

        if ($contract === null) {
            $this->notFound('Contract nicht gefunden');
        }

        $yamlContent = $_POST['yaml_content'] ?? '';
        $newVersion = trim($_POST['new_version'] ?? '');
        $changeDescription = trim($_POST['change_description'] ?? '');

        if ($yamlContent === '' || $newVersion === '') {
            if ($isHtmx) {
                $this->htmxError('YAML-Inhalt und neue Version sind erforderlich.');

                return;
            }
            $_SESSION['error'] = 'YAML-Inhalt und neue Version sind erforderlich.';
            $this->redirect('/contracts/' . $id . '/edit');
        }

        // YAML-Syntax validieren
        try {
            yaml_parse($yamlContent);
        } catch (\Exception $e) {
            if ($isHtmx) {
                $this->htmxError('Ungültige YAML-Syntax: ' . $e->getMessage());

                return;
            }
            $_SESSION['error'] = 'Ungültige YAML-Syntax: ' . $e->getMessage();
            $this->redirect('/contracts/' . $id . '/edit');
        }

        $this->repository->createNewVersion(
            (int) $id,
            $yamlContent,
            $newVersion,
            $changeDescription
        );

        if ($isHtmx) {
            $this->htmxRedirect('/contracts/' . $id);

            return;
        }

        $_SESSION['success'] = 'Contract auf Version ' . $newVersion . ' aktualisiert.';
        $this->redirect('/contracts/' . $id);
    }

    /**
     * POST /contracts/{id}/validate
     */
    public function validate(string $id): void
    {
        $this->requireCsrf();

        $contract = $this->repository->findById((int) $id);

        if ($contract === null) {
            $this->notFound('Contract nicht gefunden');
        }

        $result = $this->repository->runValidation((int) $id);

        if ($this->isHtmxRequest()) {
            $alertClass = $result['result'] === 'passed' ? 'success' : 'error';
            echo '<div class="alert alert--' . $alertClass . '">';
            echo 'Validierung: <strong>' . htmlspecialchars($result['result']) . '</strong> ';
            echo '(Critical: ' . $result['critical'] . ', Major: ' . $result['major'] . ', Minor: ' . $result['minor'] . ')';
            echo '</div>';

            return;
        }

        $_SESSION['validation_result'] = $result;
        $this->redirect('/contracts/' . $id);
    }

    /**
     * POST /contracts/{id}/deprecate
     */
    public function deprecate(string $id): void
    {
        $this->requireCsrf();

        $contract = $this->repository->findById((int) $id);

        if ($contract === null) {
            $this->notFound('Contract nicht gefunden');
        }

        $this->repository->deprecate((int) $id);

        if ($this->isHtmxRequest()) {
            $this->htmxRedirect('/contracts/' . $id);

            return;
        }

        $_SESSION['success'] = 'Contract als deprecated markiert.';
        $this->redirect('/contracts/' . $id);
    }
}
← Übersicht Graph