skip to Main Content

I want use Ben Sampo Package for enum in laravel.
this package has a property named ‘description’ as new property.
but I can’t add extra properties(attributes) to my enums.

I want to have an enum ‘status’ that has a ‘isfinal’ attribute. to determine if this key is the final or not?

I added an ‘IsFinal’ class, to attributes folder, such as ‘description’ class.
and added two methods ‘getAttributeDescription’ and ‘getDescription’, for isFinal.
but below code returns null for "isFinal’:
$descriptionAttributes = $constReflection->getAttributes(IsFinal::class);
dd($descriptionAttributes);

while for description returns enum reflectionclass constant, and works. but not work for ‘is_final’.
I really need to add some attributes to some enums.
is there any way ?

I checked this package , too. it’s so good and really easy to add extra properties. but I need localization too, and it doesn’t have, by default.

Edit:
the enum I need, is something like this:

final class Status1 extends Enum
{
#[Color('red')]
#[Description('Initial status')]
#[IsFinal(false)]    
const Initial = 1;

#[Color('blue')]
#[Description('suspended status')]
#[IsFinal(false)] 
const Pending = 2;

#[Color('white')]
#[Description('completed status')]
#[IsFinal(true)] 
const Completed = 3;

#[Color('red')]
#[Description('canceled status')]
#[IsFinal(true)] 
const Canceled = 4;
 }

2

Answers


  1. For BenSampo Package, you can follow a way like this:
    Create a Trait:

    <?php
    
    namespace AppTraits;
    
    /**
     * Get Enum Description
     */
    trait GetEnumDescription
    {
        private static $thisClass;
    
        public static function getCustomEnumDescription($enumValue = 0)
        {
            return __(self::getEnumDescription(intval($enumValue)));
        }
    
        private static function getEnumDescription($enumValue = 0)
        {
            self::$thisClass = static::class;
            $key = self::$thisClass::getKey($enumValue);
            return ucwords(str_replace('_', ' ', $key));
        }
    
        public static function getCustomInstances()
        {
            return array_map(
                function ($constantValue) {
                    $newStatic = new static($constantValue);
                    $newStatic = (array) $newStatic;
                    $newStatic['custom_description'] = self::getCustomEnumDescription($constantValue);
                    $newStatic = (object) $newStatic;
                    return $newStatic;
                },
                static::getConstants(),
            );
        }
    }
    

    Create an Enum (I usually do enum values with numeric and variable names with snake case. You can customize the methods according to you):

    <?php
    
    declare(strict_types=1);
    
    namespace AppEnums;
    
    use AppTraitsGetEnumDescription;
    use BenSampoEnumEnum;
    
    /**
     * Menu item types
     */
    final class MenuItemType extends Enum
    {
        use GetEnumDescription;
    
        const both = 0;
        const only_customer = 1;
        const only_vendor = 2;
        const closed = 3;
    }
    

    Make sure you use GetEnumDescription Trait. Example instances:

    // app()->setLocale('tr');
    // dd(MenuItemType::getCustomInstances());
    // RESULT:
    array:4 [▼
      "both" => {#1156 ▼
        +"value": 0
        +"key": "both"
        +"description": "Both"
        +"custom_description": "Her ikisi de"
      }
      "only_customer" => {#1157 ▼
        +"value": 1
        +"key": "only_customer"
        +"description": "Only customer"
        +"custom_description": "Sadece müşteri"
      }
      "only_vendor" => {#1159 ▼
        +"value": 2
        +"key": "only_vendor"
        +"description": "Only vendor"
        +"custom_description": "Sadece bayi"
      }
      "closed" => {#1158 ▼
        +"value": 3
        +"key": "closed"
        +"description": "Closed"
        +"custom_description": "Closed"
      }
    ]
    

    Example:

    public static function getCustomInstances()
    {
        return array_map(
            function ($constantValue) {
                $newStatic = new static($constantValue);
                $newStatic = (array) $newStatic;
                $newStatic['custom_description'] = self::getCustomEnumDescription($constantValue);
                $newStatic['color'] = 'red';
                $newStatic['is_final'] = true;
                $newStatic = (object) $newStatic;
                return $newStatic;
            },
            static::getConstants(),
        );
    }
    

    Result:

    // after attributes added: dd(MenuItemType::getCustomInstances());
    array:4 [▼
      "both" => {#1156 ▼
        +"value": 0
        +"key": "both"
        +"description": "Both"
        +"custom_description": "Her ikisi de"
        +"color": "red"
        +"is_final": true
      }
      "only_customer" => {#1157 ▼
        +"value": 1
        +"key": "only_customer"
        +"description": "Only customer"
        +"custom_description": "Sadece müşteri"
        +"color": "red"
        +"is_final": true
      }
      "only_vendor" => {#1158 ▼
        +"value": 2
        +"key": "only_vendor"
        +"description": "Only vendor"
        +"custom_description": "Sadece bayi"
        +"color": "red"
        +"is_final": true
      }
      "closed" => {#1159 ▼
        +"value": 3
        +"key": "closed"
        +"description": "Closed"
        +"custom_description": "Kapalı"
        +"color": "red"
        +"is_final": true
      }
    ]
    
    Login or Signup to reply.
  2. The BenSampo Laravel Enum package is fantastic for setting up enums with ease in Laravel. However, adding additional custom attributes can be a bit tricky, as it’s not natively supported in the package at the moment.

    Here are a couple of possible approaches to achieve your goal:

    1. Extend the Enum class with custom methods:

    You can extend the base Enum class to support additional attributes. However, this requires modifying the Enum class itself, which might not be ideal if you’re working in a team or planning on updating the package in the future.

        namespace AppEnums;
    
    use BenSampoEnumEnum as BaseEnum;
    
    class Enum extends BaseEnum
    {
        public static function isFinal($value) {
            // define the logic here
        }
    }
    

    And then use this base class for your enums:

    namespace AppEnums;
    
    class Status extends Enum
    {
        const DRAFT = 0;
        const FINAL = 1;
        
        public static function getDescription($value): string
        {
            if ($value === self::FINAL) {
                return 'Final';
            }
    
            return parent::getDescription($value);
        }
    }
    

    With the above method, you can now check if an enum value is final or not:

    Status::isFinal(Status::FINAL); // Should return true
    
    1. Use additional Enum classes:

    Another approach could be to create separate Enums for these special cases. For example, you can have FinalStatus enum class for statuses that are final.

    namespace AppEnums;
    
    use BenSampoEnumEnum;
    
    final class FinalStatus extends Enum
    {
        const PUBLISHED = 1;
        // Add more final statuses here
    }
    

    You can then use Laravel’s localization features to handle the localization of your enums. You would create language files for each language you want to support, and use the __() function in your application code to retrieve the localized string.

    In any case, the cleanest solution would be to have the package support additional attributes natively. You might consider creating an issue or a pull request on the package’s GitHub repository to see if the maintainers would be open to such a feature.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search