laravel-enum-translatable maintained by osama-98
Laravel Enum Translatable
A Laravel package that extends PHP 8.2 backed enums with first-class translation support, fluent array helpers, and safe comparison utilities — all through composable traits.
References: Medium Article · Laravel News
Table of Contents
- Requirements
- Installation
- Quick Start
- Configuration
- Available Traits
- Generating Enums
- Usage
- Real-World Examples
- Testing
- Changelog
- Credits
- License
Requirements
- PHP 8.2 or higher
- Laravel 11.0 or higher
Installation
Install the package via Composer:
composer require osama-98/laravel-enum-translatable
Quick Start
Step 1. Generate an enum using the Artisan command:
php artisan make:enum OrderStatus
Step 2. Define your cases and apply the trait:
enum OrderStatusEnum: string
{
use EnumTranslatable;
case PENDING = 'pending';
case SHIPPED = 'shipped';
case DELIVERED = 'delivered';
}
Step 3. Add translation entries in lang/en/enums.php:
return [
'order_statuses' => [
'pending' => 'Pending',
'shipped' => 'Shipped',
'delivered' => 'Delivered',
],
];
Step 4. Use the enum in your application:
OrderStatusEnum::PENDING->trans(); // 'Pending'
OrderStatusEnum::PENDING->trans('ar'); // 'قيد الانتظار'
OrderStatusEnum::toArrayTrans(); // [['value' => 'pending', 'name' => 'Pending'], ...]
Configuration
Publish the configuration file to customise supported locales and modular support:
php artisan vendor:publish --tag="laravel-enums-config"
// config/laravel-enums.php
return [
/*
|--------------------------------------------------------------------------
| Supported Locales
|--------------------------------------------------------------------------
| The locales that allTrans() will return translations for.
*/
'supported_locales' => ['en'],
/*
|--------------------------------------------------------------------------
| Modular Support
|--------------------------------------------------------------------------
| Enable this if you use a module system such as nWidart/laravel-modules.
| Translations will be loaded from each module's namespace automatically.
*/
'modular_enabled' => false,
/*
|--------------------------------------------------------------------------
| Namespace Resolver
|--------------------------------------------------------------------------
| The class responsible for resolving a module's translation namespace.
| Extend TranslationNamespaceResolver to customise the resolution logic.
*/
'namespace_resolver' => \Osama\LaravelEnums\TranslationNamespaceResolver::class,
];
Available Traits
The package provides three traits that compose on top of one another:
EnumTranslatable
└── EnumArrayable
└── EnumWrappable
| Trait | Intended Use |
|---|---|
EnumTranslatable |
Enums that require translated labels. Includes all traits below. |
EnumArrayable |
Enums used for filtering or listing, without translation. |
EnumWrappable |
Enums that only need comparison and safe-casting helpers. |
Generating Enums
Use the make:enum Artisan command to scaffold a new enum class:
# String-backed with EnumTranslatable (default)
php artisan make:enum OrderStatus
# Integer-backed
php artisan make:enum OrderStatus --int
# With EnumArrayable
php artisan make:enum OrderStatus --arrayable
# With EnumWrappable
php artisan make:enum OrderStatus --wrappable
Note: The
--arrayableflag already includesEnumWrappableinternally. There is no need to combine both flags.
Generated files are placed in app/Enums/. Nested namespaces are supported using /:
php artisan make:enum Admin/UserStatus
# Generates: app/Enums/Admin/UserStatusEnum.php
# Namespace: App\Enums\Admin
The Enum suffix is appended automatically if it is not included in the provided name.
Usage
All examples in this section use the following enum definition:
<?php
namespace App\Enums;
use Osama\LaravelEnums\Concerns\EnumTranslatable;
enum CourseStatusEnum: string
{
use EnumTranslatable;
case DRAFT = 'draft';
case PENDING = 'pending';
case PUBLISHED = 'published';
}
Translation Key Convention
The translation key is derived automatically from the enum class name by applying the following rules:
- Strip the
Enumsuffix - Convert to
snake_case - Pluralise
- Nest under the
enumskey
CourseStatusEnum => enums.course_statuses
Create one enums.php translation file per locale inside your lang/ directory:
lang/
├── en/
│ └── enums.php
└── ar/
└── enums.php
// lang/en/enums.php
return [
'course_statuses' => [
'draft' => 'Draft',
'draft_description' => ':name is currently in draft mode.',
'pending' => 'Pending',
'pending_description' => ':name is currently pending review.',
'published' => 'Published',
'published_description' => 'Your post has been published.',
],
];
// lang/ar/enums.php
return [
'course_statuses' => [
'draft' => 'مسودة',
'draft_description' => ':name في وضع المسودة حاليًا.',
'pending' => 'قيد المراجعة',
'pending_description' => ':name قيد المراجعة حاليًا.',
'published' => 'منشور',
'published_description' => 'تم نشر المنشور.',
],
];
EnumTranslatable
trans(?string $locale = null, ?string $context = null, array $replace = []): string
Returns the translated label for the current case. Defaults to the application locale. Falls back to the raw enum value if no translation is found.
$status = CourseStatusEnum::DRAFT;
$status->trans(); // 'Draft' (current application locale)
$status->trans('ar'); // 'مسودة'
$status->trans('en'); // 'Draft'
The optional $context parameter appends a suffix to the translation key, enabling multiple label variants per case:
CourseStatusEnum::PUBLISHED->trans(context: 'description');
// 'Your post has been published.'
The optional $replace parameter passes replacement variables into the translation string, identical to Laravel's __() helper:
CourseStatusEnum::DRAFT->trans(context: 'description', replace: ['name' => 'Course A']);
// 'Course A is currently in draft mode.'
allTrans(): array
Returns translations for all locales defined in the supported_locales configuration option.
CourseStatusEnum::DRAFT->allTrans();
// ['en' => 'Draft', 'ar' => 'مسودة']
toArrayTrans(?string $locale = null): array
Returns all cases as an array of ['value', 'name'] pairs. Uses the current application locale when $locale is null.
CourseStatusEnum::toArrayTrans(); // current locale
CourseStatusEnum::toArrayTrans('ar'); // Arabic
CourseStatusEnum::toArrayTrans('en'); // English
// [
// ['value' => 'draft', 'name' => 'Draft'],
// ['value' => 'pending', 'name' => 'Pending'],
// ['value' => 'published', 'name' => 'Published'],
// ]
toTransCollection(?string $locale = null): Collection
Identical to toArrayTrans() but returns a Laravel Collection.
CourseStatusEnum::toTransCollection('ar');
// Collection([
// ['value' => 'draft', 'name' => 'مسودة'],
// ['value' => 'pending', 'name' => 'قيد المراجعة'],
// ['value' => 'published', 'name' => 'منشور'],
// ])
object(): array
Returns the current case as a ['value', 'name'] pair using the current locale. Suitable for use in API responses.
CourseStatusEnum::DRAFT->object();
// ['value' => 'draft', 'name' => 'Draft']
transKey(): string
Returns the full translation key for the current case.
CourseStatusEnum::DRAFT->transKey();
// 'enums.course_statuses.draft'
getTransKey(): string
Returns the translation key for the enum class, without a specific case appended.
CourseStatusEnum::getTransKey();
// 'enums.course_statuses'
EnumArrayable
names(): array · values(): array · toArray(): array
CourseStatusEnum::names(); // ['DRAFT', 'PENDING', 'PUBLISHED']
CourseStatusEnum::values(); // ['draft', 'pending', 'published']
CourseStatusEnum::toArray(); // ['draft' => 'DRAFT', 'pending' => 'PENDING', 'published' => 'PUBLISHED']
toCollection(): Collection
Identical to toArray() but returns a Laravel Collection.
CourseStatusEnum::toCollection();
// Collection(['draft' => 'DRAFT', 'pending' => 'PENDING', 'published' => 'PUBLISHED'])
CourseStatusEnum::toCollection()->keys(); // ['draft', 'pending', 'published']
CourseStatusEnum::toCollection()->values(); // ['DRAFT', 'PENDING', 'PUBLISHED']
only(array $values): array · except(array $values): array
Filter cases by value. Accepts raw string values or enum instances.
CourseStatusEnum::only(['draft', 'pending']);
// [CourseStatusEnum::DRAFT, CourseStatusEnum::PENDING]
CourseStatusEnum::except([CourseStatusEnum::PUBLISHED]);
// [CourseStatusEnum::DRAFT, CourseStatusEnum::PENDING]
randomCase(): self · randomValue(): string
Returns a random case or raw value. Accepts an optional exclusion list.
CourseStatusEnum::randomCase(); // e.g. CourseStatusEnum::PENDING
CourseStatusEnum::randomValue(); // e.g. 'pending'
CourseStatusEnum::randomCase(except: CourseStatusEnum::DRAFT);
CourseStatusEnum::randomValue(except: ['draft', 'pending']); // always returns 'published'
matching(string $pattern): array · notMatching(string $pattern): array
Filter cases using a wildcard pattern. Matching is case-insensitive; * matches any sequence of characters.
CourseStatusEnum::matching('*ed'); // [PUBLISHED]
CourseStatusEnum::notMatching('*ed'); // [DRAFT]
The following convenience methods are also available:
CourseStatusEnum::startsWith('p'); // [PENDING, PUBLISHED]
CourseStatusEnum::endsWith('ed'); // [PUBLISHED]
CourseStatusEnum::contains('ish'); // [PUBLISHED]
EnumWrappable
wrap(BackedEnum|string|null $value, bool $strict = true): ?static
Safely casts a string or an existing enum instance to the enum type. Returns null for empty or null values. Set strict: false to use tryFrom() instead of from(), which suppresses exceptions on invalid input.
CourseStatusEnum::wrap('draft'); // CourseStatusEnum::DRAFT
CourseStatusEnum::wrap(CourseStatusEnum::DRAFT); // CourseStatusEnum::DRAFT
CourseStatusEnum::wrap(null); // null
CourseStatusEnum::wrap('invalid', strict: false); // null
is(BackedEnum|string $value): bool · isNot(BackedEnum|string $value): bool
$status = CourseStatusEnum::DRAFT;
$status->is('draft'); // true
$status->is(CourseStatusEnum::DRAFT); // true
$status->isNot(CourseStatusEnum::PUBLISHED); // true
isAny(array $values): bool · isNotAny(array $values): bool
$status->isAny(['draft', 'pending']); // true
$status->isAny([CourseStatusEnum::PUBLISHED]); // false
$status->isNotAny([CourseStatusEnum::PENDING, CourseStatusEnum::PUBLISHED]); // true
Real-World Examples
Eloquent Model
Cast a database column directly to an enum using Laravel's built-in casting:
protected function casts(): array
{
return [
'status' => CourseStatusEnum::class,
];
}
API Resource
Use object() to return a structured value and name pair in API responses:
public function toArray(Request $request): array
{
return [
'id' => $this->id,
'title' => $this->title,
'status' => $this->status->object(),
// ['value' => 'draft', 'name' => 'Draft']
];
}
Select Dropdown
Return all cases as translatable options for a frontend select component:
public function create(): JsonResponse
{
return response()->json([
'statuses' => CourseStatusEnum::toArrayTrans(),
]);
}
Testing
composer test
Changelog
Please refer to CHANGELOG.md for a detailed list of changes in each release.
Credits
License
This package is open-sourced software licensed under the MIT License.