Guide

Controllers et réponses

Ce que fournit `AbstractController` et quand une couche applicative commune devient utile.

Base du framework : AbstractController

Le framework fournit AbstractController avec des helpers pour les requests, responses et services, notamment view(), url(), validator(), flash(), filesystem(), upload(), translator() et breadcrumb().

example.php
<?php

declare(strict_types=1);

namespace App\Controllers;

use Lemonade\Framework\Core\AbstractController;
use Psr\Http\Message\ResponseInterface;

final class ArticleController extends AbstractController
{
    public function detail(int $id): ResponseInterface
    {
        return $this->json([
            'id' => $id,
            'expects_json' => $this->expectsJson(),
        ]);
    }
}

Controller applicatif commun

L’application peut ajouter facultativement AppController extends AbstractController. Il est utile pour le rendu partagé, les données communes, les metadata, les breadcrumbs ou de petits helpers. Ce n’est pas une exigence du framework.

example.php
<?php

declare(strict_types=1);

namespace App\Controllers;

use Lemonade\Framework\Core\AbstractController;
use Psr\Http\Message\ResponseInterface;

abstract class AppController extends AbstractController
{
    /**
     * @param array<string, mixed> $data
     */
    protected function page(string $view, array $data = [], int $status = 200): ResponseInterface
    {
        return $this->html(
            $this->view()->template(
                'layouts.app',
                $view,
                $data,
            ),
            $status,
        );
    }
}

Couches supplémentaires dans les grandes applications

Dans une application plus importante, vous pouvez ajouter des couches au-dessus de AppController pour le site public, l’administration, la gestion de locale ou les canonical redirects. C’est un choix d’architecture applicative, pas une hiérarchie imposée par le framework.

example.php
AbstractController
    ↓
Optional application base controller
    ↓
Optional specialized controller
    ↓
Concrete controller

Les controllers PSR purs sont également valides

Un controller n’a pas besoin d’hériter de AbstractController si vous préférez construire directement les réponses PSR avec ResponseFactoryInterface et StreamFactoryInterface.

example.php
<?php

declare(strict_types=1);

namespace App\Controllers;

use Psr\Http\Message\ResponseFactoryInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\StreamFactoryInterface;

final class StatusController
{
    public function __construct(
        private readonly ResponseFactoryInterface $responses,
        private readonly StreamFactoryInterface $streams,
    ) {}

    public function index(): ResponseInterface
    {
        return $this->responses
            ->createResponse(200)
            ->withHeader('Content-Type', 'text/html; charset=UTF-8')
            ->withBody($this->streams->createStream('<h1>Status OK</h1>'));
    }
}