Les administrateurs peuvent désormais configurer l'identité visuelle de leur établissement : upload d'un logo (PNG/JPG, redimensionné automatiquement via Imagick) et choix d'une couleur principale appliquée aux boutons et à la navigation. La couleur est validée côté client et serveur pour garantir la conformité WCAG AA (contraste ≥ 4.5:1 sur fond blanc). Les personnalisations sont injectées dynamiquement via CSS variables et visibles immédiatement après sauvegarde.
49 lines
1.5 KiB
PHP
49 lines
1.5 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Administration\Application\Command\UploadLogo;
|
|
|
|
use App\Administration\Application\Service\LogoUploader;
|
|
use App\Administration\Domain\Model\SchoolBranding\SchoolBranding;
|
|
use App\Administration\Domain\Model\SchoolClass\SchoolId;
|
|
use App\Administration\Domain\Repository\SchoolBrandingRepository;
|
|
use App\Shared\Domain\Clock;
|
|
use App\Shared\Domain\Tenant\TenantId;
|
|
use Symfony\Component\Messenger\Attribute\AsMessageHandler;
|
|
|
|
#[AsMessageHandler(bus: 'command.bus')]
|
|
final readonly class UploadLogoHandler
|
|
{
|
|
public function __construct(
|
|
private SchoolBrandingRepository $brandingRepository,
|
|
private LogoUploader $logoUploader,
|
|
private Clock $clock,
|
|
) {
|
|
}
|
|
|
|
public function __invoke(UploadLogoCommand $command): SchoolBranding
|
|
{
|
|
$tenantId = TenantId::fromString($command->tenantId);
|
|
$schoolId = SchoolId::fromString($command->schoolId);
|
|
$now = $this->clock->now();
|
|
|
|
$branding = $this->brandingRepository->findBySchoolId($schoolId, $tenantId);
|
|
|
|
if ($branding === null) {
|
|
$branding = SchoolBranding::creer(
|
|
schoolId: $schoolId,
|
|
tenantId: $tenantId,
|
|
createdAt: $now,
|
|
);
|
|
}
|
|
|
|
$logoUrl = $this->logoUploader->upload($command->file, $tenantId, $branding->logoUrl);
|
|
$branding->changerLogo($logoUrl, $now);
|
|
|
|
$this->brandingRepository->save($branding);
|
|
|
|
return $branding;
|
|
}
|
|
}
|