domthomas-dev / laravel-localized-enum
A Laravel package for managing localized enums with automatic translation support
Requires
- php: ^8.1
- illuminate/support: ^10.0|^11.0
- illuminate/translation: ^10.0|^11.0
Requires (Dev)
- orchestra/testbench: ^8.0|^9.0
- pestphp/pest: ^2.0
- pestphp/pest-plugin-laravel: ^2.0
README
Laravel Localized Enum
A Laravel package that provides automatic localization support for PHP enums, making it easy to display translated enum values in your application.
Installation
You can install the package via Composer:
composer require domthomas-dev/laravel-localized-enum
The package will automatically register its service provider.
Configuration
Optionally, you can publish the configuration file:
php artisan vendor:publish --tag=localized-enum-config
This will create a config/localized-enum.php
file where you can customize:
return [ // Default label type when none is specified 'default_label' => 'label', // Translation file name (without .php extension) 'translation_file' => 'enums', ];
Usage
Basic Usage
Add the LocalizedEnum
trait to your enum:
<?php namespace App\Enums; use DomThomas\LocalizedEnum\LocalizedEnum; enum ContactType: string { use LocalizedEnum; case EMAIL = 'email'; case PHONE = 'phone'; case SMS = 'sms'; }
Translation Files
Create translation files for your enums in your resources/lang
directory:
// resources/lang/en/enums.php <?php use App\Enums\ContactType; return [ ContactType::class => [ 'label' => [ ContactType::EMAIL->name => 'Email', ContactType::PHONE->name => 'Phone', ContactType::SMS->name => 'SMS', ], 'description' => [ ContactType::EMAIL->name => 'Send via email', ContactType::PHONE->name => 'Call by phone', ContactType::SMS->name => 'Send text message', ], ], ];
// resources/lang/fr/enums.php <?php use App\Enums\ContactType; return [ ContactType::class => [ 'label' => [ ContactType::EMAIL->name => 'E-mail', ContactType::PHONE->name => 'Téléphone', ContactType::SMS->name => 'SMS', ], 'description' => [ ContactType::EMAIL->name => 'Envoyer par e-mail', ContactType::PHONE->name => 'Appeler par téléphone', ContactType::SMS->name => 'Envoyer un SMS', ], ], ];
Getting Labels
$contact = new Contact(); $contact->type = ContactType::EMAIL; // Get default label echo $contact->type->label(); // "Email" // Get label in specific locale echo $contact->type->label(locale: 'fr'); // "E-mail"
Multiple Label Types
You can define multiple label types for the same enum as shown in the translation files above:
// Get description label echo ContactType::EMAIL->label('description'); // "Send via email" // Get default label (uses 'label' key) echo ContactType::EMAIL->label(); // "Email"
For Select Inputs
Generate arrays suitable for HTML select inputs:
// Get all options for select $options = ContactType::forSelect(); // Returns: ['email' => 'Email', 'phone' => 'Phone', 'sms' => 'SMS'] // With placeholder $options = ContactType::forSelect(placeHolder: 'Choose contact type'); // Returns: ['' => 'Choose contact type', 'email' => 'Email', 'phone' => 'Phone', 'sms' => 'SMS'] // With specific label type $options = ContactType::forSelect(label: 'description'); // Returns: ['email' => 'Send via email', 'phone' => 'Call by phone', 'sms' => 'Send text message'] // With specific locale $options = ContactType::forSelect(locale: 'fr'); // Returns: ['email' => 'E-mail', 'phone' => 'Téléphone', 'sms' => 'SMS'] // Exclude specific cases $options = ContactType::forSelect(excepted: [ContactType::SMS]); // Returns only EMAIL and PHONE options // Returns: ['email' => 'Email', 'phone' => 'Phone'] // Include only specific cases $options = ContactType::forSelect(only: [ContactType::EMAIL, ContactType::PHONE]); // Returns only EMAIL and PHONE options // Returns: ['email' => 'Email', 'phone' => 'Phone'] // Get structured options array $options = ContactType::options(); // Returns: [ // ['value' => 'email', 'label' => 'Email'], // ['value' => 'phone', 'label' => 'Phone'], // ['value' => 'sms', 'label' => 'SMS'] // ] // With custom label and locale $options = ContactType::options(label: 'description', locale: 'fr');
Blade Usage
<!-- In a select input --> <select name="contact_type"> @foreach(ContactType::forSelect(placeHolder: 'Select type') as $value => $label) <option value="{{ $value }}">{{ $label }}</option> @endforeach </select> <!-- Select with filtered options --> <select name="preferred_contact"> @foreach(ContactType::forSelect(placeHolder: 'Choose method', excepted: [ContactType::SMS]) as $value => $label) <option value="{{ $value }}">{{ $label }}</option> @endforeach </select> <!-- Display enum label --> <p>Contact type: {{ $contact->type->label() }}</p> <p>Description: {{ $contact->type->label('description') }}</p>
Translation Key Format
The package automatically generates translation keys using this format:
{translation_file}.{EnumClass}.{label_type}.{case_name}
For example (with default config):
App\Enums\ContactType::EMAIL
→enums.App\Enums\ContactType.label.EMAIL
- With description:
enums.App\Enums\ContactType.description.EMAIL
You can customize the translation file name and default label type in the configuration.
Utility Methods
// Get all enum values as array $values = ContactType::values(); // Returns: ['email', 'phone', 'sms'] // Filter enum cases $filtered = ContactType::filterCases(excepted: [ContactType::SMS]); // Exclude SMS $onlyEmailPhone = ContactType::filterCases(only: [ContactType::EMAIL, ContactType::PHONE]); // Only EMAIL and PHONE
Advanced Features
Fallback Behavior
If a translation key is not found, the package will fall back to the enum case name:
// If translation doesn't exist, returns the case name echo ContactType::EMAIL->label(); // "EMAIL" (if no translation found)
Translation Structure
The translation structure uses the enum class as the top-level key in your translation files (default: resources/lang/{locale}/enums.php
):
use App\Enums\ContactType; return [ ContactType::class => [ 'label' => [ ContactType::EMAIL->name => 'Email', ContactType::PHONE->name => 'Phone', ], 'description' => [ ContactType::EMAIL->name => 'Send via email', ContactType::PHONE->name => 'Call by phone', ], // You can add custom label types 'short' => [ ContactType::EMAIL->name => 'E', ContactType::PHONE->name => 'P', ], ], ];
Note: If you change the translation_file
config to something other than 'enums', make sure to update your file names accordingly (e.g., translations.php
if you set it to 'translations').
## Testing
```bash
composer test
License
The MIT License (MIT). Please see License File for more information.