Skip to content

Commit 1d6c276

Browse files
committed
chore: Initial commit
0 parents  commit 1d6c276

16 files changed

+964
-0
lines changed

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
build/
2+
vendor/
3+
composer.lock
4+
.phpunit.result.cache
5+
.pest/

README.md

Lines changed: 238 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,238 @@
1+
# Laravel Localized Enum
2+
3+
A Laravel package that provides automatic localization support for PHP enums, making it easy to display translated enum values in your application.
4+
5+
## Installation
6+
7+
You can install the package via Composer:
8+
9+
```bash
10+
composer require domthomas-dev/laravel-localized-enum
11+
```
12+
13+
The package will automatically register its service provider.
14+
15+
## Usage
16+
17+
### Basic Usage
18+
19+
Add the `LocalizedEnum` trait to your enum:
20+
21+
```php
22+
<?php
23+
24+
namespace App\Enums;
25+
26+
use DomThomas\LocalizedEnum\LocalizedEnum;
27+
28+
enum ContactType: string
29+
{
30+
use LocalizedEnum;
31+
32+
case EMAIL = 'email';
33+
case PHONE = 'phone';
34+
case SMS = 'sms';
35+
}
36+
```
37+
38+
### Translation Files
39+
40+
Create translation files for your enums in your `resources/lang` directory:
41+
42+
```php
43+
// resources/lang/en/enums.php
44+
<?php
45+
46+
use App\Enums\ContactType;
47+
48+
return [
49+
ContactType::class => [
50+
'label' => [
51+
ContactType::EMAIL->name => 'Email',
52+
ContactType::PHONE->name => 'Phone',
53+
ContactType::SMS->name => 'SMS',
54+
],
55+
'description' => [
56+
ContactType::EMAIL->name => 'Send via email',
57+
ContactType::PHONE->name => 'Call by phone',
58+
ContactType::SMS->name => 'Send text message',
59+
],
60+
],
61+
];
62+
```
63+
64+
```php
65+
// resources/lang/fr/enums.php
66+
<?php
67+
68+
use App\Enums\ContactType;
69+
70+
return [
71+
ContactType::class => [
72+
'label' => [
73+
ContactType::EMAIL->name => 'E-mail',
74+
ContactType::PHONE->name => 'Téléphone',
75+
ContactType::SMS->name => 'SMS',
76+
],
77+
'description' => [
78+
ContactType::EMAIL->name => 'Envoyer par e-mail',
79+
ContactType::PHONE->name => 'Appeler par téléphone',
80+
ContactType::SMS->name => 'Envoyer un SMS',
81+
],
82+
],
83+
];
84+
```
85+
86+
### Getting Labels
87+
88+
```php
89+
$contact = new Contact();
90+
$contact->type = ContactType::EMAIL;
91+
92+
// Get default label
93+
echo $contact->type->label(); // "Email"
94+
95+
// Get label in specific locale
96+
echo $contact->type->label(null, 'fr'); // "E-mail"
97+
```
98+
99+
### Multiple Label Types
100+
101+
You can define multiple label types for the same enum as shown in the translation files above:
102+
103+
```php
104+
// Get description label
105+
echo ContactType::EMAIL->label('description'); // "Send via email"
106+
107+
// Get default label (uses 'label' key)
108+
echo ContactType::EMAIL->label(); // "Email"
109+
```
110+
111+
### For Select Inputs
112+
113+
Generate arrays suitable for HTML select inputs:
114+
115+
```php
116+
// Get all options for select
117+
$options = ContactType::forSelect();
118+
// Returns: ['email' => 'Email', 'phone' => 'Phone', 'sms' => 'SMS']
119+
120+
// With placeholder
121+
$options = ContactType::forSelect(null, null, 'Choose contact type');
122+
// Returns: ['' => 'Choose contact type', 'email' => 'Email', ...]
123+
124+
// With specific label type
125+
$options = ContactType::forSelect('description');
126+
127+
// With specific locale
128+
$options = ContactType::forSelect(null, 'fr');
129+
130+
// Exclude specific cases
131+
$options = ContactType::forSelect(null, null, null, [ContactType::SMS]);
132+
// Returns only EMAIL and PHONE options
133+
134+
// Include only specific cases
135+
$options = ContactType::forSelect(null, null, null, null, [ContactType::EMAIL, ContactType::PHONE]);
136+
// Returns only EMAIL and PHONE options
137+
138+
// Get structured options array
139+
$options = ContactType::options();
140+
// Returns: [
141+
// ['value' => 'email', 'label' => 'Email'],
142+
// ['value' => 'phone', 'label' => 'Phone'],
143+
// ['value' => 'sms', 'label' => 'SMS']
144+
// ]
145+
```
146+
147+
### Blade Usage
148+
149+
```blade
150+
<!-- In a select input -->
151+
<select name="contact_type">
152+
@foreach(ContactType::forSelect(null, null, 'Select type') as $value => $label)
153+
<option value="{{ $value }}">{{ $label }}</option>
154+
@endforeach
155+
</select>
156+
157+
<!-- Select with filtered options -->
158+
<select name="preferred_contact">
159+
@foreach(ContactType::forSelect(null, null, 'Choose method', [ContactType::SMS]) as $value => $label)
160+
<option value="{{ $value }}">{{ $label }}</option>
161+
@endforeach
162+
</select>
163+
164+
<!-- Display enum label -->
165+
<p>Contact type: {{ $contact->type->label() }}</p>
166+
<p>Description: {{ $contact->type->label('description') }}</p>
167+
```
168+
169+
## Translation Key Format
170+
171+
The package automatically generates translation keys using this format:
172+
173+
```
174+
{EnumClass}.{label_type}.{case_name}
175+
```
176+
177+
For example:
178+
- `App\Enums\ContactType::EMAIL``App\Enums\ContactType.label.EMAIL`
179+
- With description: `App\Enums\ContactType.description.EMAIL`
180+
181+
### Utility Methods
182+
183+
```php
184+
// Get all enum values as array
185+
$values = ContactType::values();
186+
// Returns: ['email', 'phone', 'sms']
187+
188+
// Filter enum cases
189+
$filtered = ContactType::filterCases([ContactType::SMS]); // Exclude SMS
190+
$onlyEmailPhone = ContactType::filterCases(null, [ContactType::EMAIL, ContactType::PHONE]); // Only EMAIL and PHONE
191+
```
192+
193+
## Advanced Features
194+
195+
### Fallback Behavior
196+
197+
If a translation key is not found, the package will fall back to the enum case name:
198+
199+
```php
200+
// If translation doesn't exist, returns the case name
201+
echo ContactType::EMAIL->label(); // "EMAIL" (if no translation found)
202+
```
203+
204+
### Translation Structure
205+
206+
The translation structure uses the enum class as the top-level key:
207+
208+
```php
209+
use App\Enums\ContactType;
210+
211+
return [
212+
ContactType::class => [
213+
'label' => [
214+
ContactType::EMAIL->name => 'Email',
215+
ContactType::PHONE->name => 'Phone',
216+
],
217+
'description' => [
218+
ContactType::EMAIL->name => 'Send via email',
219+
ContactType::PHONE->name => 'Call by phone',
220+
],
221+
// You can add custom label types
222+
'short' => [
223+
ContactType::EMAIL->name => 'E',
224+
ContactType::PHONE->name => 'P',
225+
],
226+
],
227+
];
228+
```
229+
230+
## Testing
231+
232+
```bash
233+
composer test
234+
```
235+
236+
## License
237+
238+
The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

composer.json

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
{
2+
"name": "domthomas-dev/laravel-localized-enum",
3+
"description": "A Laravel package for managing localized enums with automatic translation support",
4+
"keywords": ["laravel", "enum", "localization", "translation", "i18n"],
5+
"type": "library",
6+
"license": "MIT",
7+
"authors": [
8+
{
9+
"name": "Dom Thomas",
10+
"email": "[email protected]"
11+
}
12+
],
13+
"require": {
14+
"php": "^8.1",
15+
"illuminate/support": "^10.0|^11.0",
16+
"illuminate/translation": "^10.0|^11.0"
17+
},
18+
"require-dev": {
19+
"orchestra/testbench": "^8.0|^9.0",
20+
"pestphp/pest": "^2.0",
21+
"pestphp/pest-plugin-laravel": "^2.0"
22+
},
23+
"autoload": {
24+
"psr-4": {
25+
"DomThomas\\LocalizedEnum\\": "src/"
26+
}
27+
},
28+
"autoload-dev": {
29+
"psr-4": {
30+
"DomThomas\\LocalizedEnum\\Tests\\": "tests/"
31+
}
32+
},
33+
"extra": {
34+
"laravel": {
35+
"providers": [
36+
"DomThomas\\LocalizedEnum\\LocalizedEnumServiceProvider"
37+
]
38+
}
39+
},
40+
"minimum-stability": "stable",
41+
"prefer-stable": true,
42+
"scripts": {
43+
"test": "pest"
44+
},
45+
"config": {
46+
"allow-plugins": {
47+
"pestphp/pest-plugin": true
48+
}
49+
}
50+
}

phpunit.xml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
4+
bootstrap="vendor/autoload.php"
5+
colors="true"
6+
>
7+
<testsuites>
8+
<testsuite name="Package Test Suite">
9+
<directory suffix=".php">./tests</directory>
10+
</testsuite>
11+
</testsuites>
12+
<coverage>
13+
<include>
14+
<directory suffix=".php">./src</directory>
15+
</include>
16+
</coverage>
17+
<logging>
18+
<junit outputFile="build/report.junit.xml"/>
19+
</logging>
20+
</phpunit>

0 commit comments

Comments
 (0)