I have a Enum that implements a given interface:
namespace App\Model;
use Symfony\Contracts\Translation\TranslatableInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
enum UserRole: string implements TranslatableInterface
{
case User = 'ROLE_USER';
case ZoneManager = 'ROLE_ZONE_MANAGER';
case SuperAdmin = 'ROLE_SUPER_ADMIN';
public function trans(TranslatorInterface $translator, ?string $locale = null): string
{
return match ($this) {
self::User => $translator->trans('roles.user', locale: $locale),
self::ZoneManager => $translator->trans('roles.zone_manager', locale: $locale),
self::SuperAdmin => $translator->trans('roles.super_admin', locale: $locale),
};
}
}
I wrote a function to return an array of enum value (as string) and the corresponding translation:
private function translateEnum(\BackedEnum&TranslatableInterface $enum)
{
return array_combine(
array_map(fn(\BackedEnum $v) => $v->value, $enum::cases()),
array_map(
fn(\BackedEnum&TranslatableInterface $v) => $v->trans($this->translator),
$enum::cases()),
);
}
How can I pass UserRole enum to my function, an a "whole"? Of course UserRole::class won't work (is a string) neither UserRole alone works.
If you don't mind using static analysis, both Psalm and PHPStan support the class-string<T> type annotation.
Define your function as follows:
/**
* @param class-string<BackedEnum&TranslatableInterface> $enumClass
*/
private function translateEnum(string $enumClass)
{
return array_combine(
array_map(fn(\BackedEnum $v) => $v->value, $enum::cases()),
array_map(
fn(TranslatableInterface $v) => $v->trans($this->translator),
$enumClass::cases()),
);
}
Both Psalm and PHPStan will now complain if you pass a class string that does not implement BackedEnum&TranslatableInterface.
interface TranslatableInterface {}
enum MyBackedEnum: string implements TranslatableInterface {}
enum NotABackedEnum {}
enum NotATranslatableEnum: string {}
translateEnum(MyBackedEnum::class); // Ok
translateEnum(NotABackedEnum::class); // Error
translateEnum(NotATranslatableEnum::class); // Also an error
See here for a playground example: https://phpstan.org/r/9e56fbe5-e8c7-4300-a32c-aad79976f47c.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With