BenSampo / laravel-enum

Simple, extensible and powerful enumeration implementation for Laravel.
https://sampo.co.uk/blog/using-enums-in-laravel
MIT License
2k stars 164 forks source link

Localization no tworking when enum value contains dots "." #206

Closed DerpgonCz closed 3 years ago

DerpgonCz commented 3 years ago

Laravel localization works by splitting the translation key using dots, so by using dots in the enum value I am locked out of using localized solution.

For example, let's have an enum:

<?php

namespace App\Enums;

use BenSampo\Enum\Contracts\LocalizedEnum;
use BenSampo\Enum\Enum;

final class Permission extends Enum implements LocalizedEnum
{
    const VIEW_SETTINGS = 'settings.view';
}

The translation file is constructed like so:


<?php

use App\Enums\Permission;

return [

    /*
    |--------------------------------------------------------------------------
    | Enums
    |--------------------------------------------------------------------------
    */
    Permission::class => [
        Permission::VIEW_SETTINGS => 'Allows the user to view settings',
    ],
];

Enum ends up with interpreting the translation key as enums.App\Enums\Permission.settings.view. However, this translation key is only one level down, and no keys with dots will be parsed as a single level. The correct file - that works - is this:


<?php

use App\Enums\Permission;

return [

    /*
    |--------------------------------------------------------------------------
    | Enums
    |--------------------------------------------------------------------------
    */
    Permission::class => [
        'settings' => [ 'view => 'Allows the user to view settings' ],
    ],
];

However, this does not use the enum values.

I do not think there is a clever solution to this - without changing package code - but it could be solved by something like this:

    protected static function getLocalizedDescription($value): ?string
    {
        if (self::isLocalizable()) {
            $localizedStringKey = self::getLocalizationKey();

            if (Lang::has($localizedStringKey)) {
                $strings = Lang::get($localizedStringKey);
                if (array_key_exists($value, $strings)) {
                    return $strings[$value];
                }
            }
        }

        return null;
    }

This correctly loads all translations keys for the enum, checks if it exists, and returns it. It bypasses the original Laravel's system of retrieving translation keys, and kind of defeats the purpose and system of translations, but it is a solution.

BenSampo commented 3 years ago

This feels like an edge case, but feel free to submit a PR with tests