foundation/documentation/internationalization.md
2025-06-13 18:29:55 +02:00

4.6 KiB

Internationalization (i18n) Guide

Installation

composer require symfony/translation symfony/yaml

Core Implementation

LocaleConfig Value Object

// src/Core/Application/ValueObjects/LocaleConfig.php
final class LocaleConfig
{
    public function __construct(
        public readonly string $defaultLocale,
        public readonly array $supportedLocales,
        public readonly string $fallbackLocale,
    ) {}

    public static function fromEnvironment(): self
    {
        return new self(
            $_ENV['APP_LOCALE'] ?? 'en',
            explode(',', $_ENV['APP_SUPPORTED_LOCALES'] ?? 'en,de,fr'),
            $_ENV['APP_FALLBACK_LOCALE'] ?? 'en',
        );
    }
}

Translation Manager

// src/Core/Internalization/TranslationManagerInterface.php
interface TranslationManagerInterface
{
    public function trans(string $key, array $parameters = [], ?string $domain = null): string;
    public function setLocale(string $locale): void;
    public function addResource(string $format, mixed $resource, string $locale, ?string $domain = null): void;
}

// src/Core/Internalization/TranslationManager.php
final class TranslationManager implements TranslationManagerInterface
{
    private Translator $translator;

    public function __construct(LocaleConfig $localeConfig)
    {
        $this->translator = new Translator($localeConfig->defaultLocale);
        $this->translator->setFallbackLocales([$localeConfig->fallbackLocale]);
        $this->translator->addLoader('yaml', new YamlFileLoader());
    }

    public function trans(string $key, array $parameters = [], ?string $domain = null): string
    {
        return $this->translator->trans($key, $parameters, $domain);
    }

    public function setLocale(string $locale): void
    {
        $this->translator->setLocale($locale);
    }

    public function addResource(string $format, mixed $resource, string $locale, ?string $domain = null): void
    {
        $this->translator->addResource($format, $resource, $locale, $domain);
    }
}

Bootstrapper

// src/Core/Application/Bootstrapper/TranslationInitializer.php
class TranslationInitializer implements BootstrapperInterface
{
    public function bootstrap(InflectableContainer $container): void
    {
        $container->set(LocaleConfig::class, LocaleConfig::fromEnvironment());
        $container->bind(TranslationManagerInterface::class, TranslationManager::class, [LocaleConfig::class]);
        
        $this->loadTranslationFiles($container);
    }
    
    private function loadTranslationFiles(InflectableContainer $container): void
    {
        $manager = $container->get(TranslationManagerInterface::class);
        $config = $container->get(LocaleConfig::class);
        
        // Load framework translations
        foreach ($config->supportedLocales as $locale) {
            $file = dirname(__DIR__, 4) . "/translations/{$locale}/messages.yaml";
            if (file_exists($file)) {
                $manager->addResource('yaml', $file, $locale, 'messages');
            }
        }
        
        // Load module translations
        foreach (glob(dirname(__DIR__, 3) . '/Modules/*/translations/*/messages.yaml') as $file) {
            $parts = explode('/', $file);
            $locale = $parts[count($parts) - 2];
            $manager->addResource('yaml', $file, $locale, 'messages');
        }
    }
}

Helper Functions

// src/Core/Internalization/helpers.php
function trans(string $key, array $parameters = []): string {
    global $container;
    static $translator = null;
    $translator ??= $container->get(TranslationManagerInterface::class);
    return $translator->trans($key, $parameters);
}

function __(string $key, array $parameters = []): string {
    return trans($key, $parameters);
}

Usage

Directory Structure

translations/en/messages.yaml
translations/de/messages.yaml
src/Modules/{Module}/translations/en/messages.yaml

Translation Files (YAML)

# translations/en/messages.yaml
welcome:
  title: "Welcome to Foundation"
  message: "Hello, %name%!"
user:
  profile: "User Profile"

Controller Usage

class WelcomeController implements ControllerInterface
{
    public function __construct(private readonly TranslationManagerInterface $translator) {}
    
    public function index(): ResponseInterface
    {
        $title = $this->translator->trans('welcome.title');
        $message = __('welcome.message', ['%name%' => 'John']);
        // ...
    }
}

Environment Configuration

APP_LOCALE=en
APP_SUPPORTED_LOCALES=en,de,fr
APP_FALLBACK_LOCALE=en