Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Doctrine Enum Bundle Laravel Package

art-fatal/doctrine-enum-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require art-fatal/doctrine-enum-bundle
    

    For Symfony without Flex, register the bundle in config/bundles.php:

    ArtFatal\DoctrineEnumBundle\DoctrineEnumBundle::class => ['all' => true],
    
  2. First Use Case: Use the built-in DayOfWeek enum in an entity:

    use ArtFatal\DoctrineEnumBundle\Enum\DayOfWeek;
    use ArtFatal\DoctrineEnumBundle\Type\DayOfWeekEnumType;
    use Doctrine\ORM\Mapping as ORM;
    
    #[ORM\Entity]
    class Schedule {
        #[ORM\Column(type: DayOfWeekEnumType::NAME)]
        private ?DayOfWeek $dayOfWeek = null;
    }
    
  3. Generate Migration:

    php bin/console doctrine:migrations:diff
    php bin/console doctrine:migrations:migrate
    

Where to Look First

  • Built-in Enums: src/Enum/ in the bundle for ready-to-use enums like DayOfWeek.
  • Command: make:enum for generating custom enums interactively.
  • Examples: examples/ directory for complete usage patterns.

Implementation Patterns

Usage Patterns

  1. Built-in Enums:

    • Use DayOfWeek or other pre-defined enums directly in entities.
    • Leverage helper methods like isWeekend(), label(), or toIsoNumber().
  2. Custom Enums via Generator:

    • Run php bin/console make:enum to scaffold enums and types.
    • Follow the interactive prompts for enum name, cases, and namespaces.
    • Example output:
      Enum name: UserStatus
      Case #1: ACTIVE=active
      Case #2: INACTIVE=inactive
      
    • Generates:
      • src/Enum/UserStatus.php (enum class).
      • src/Type/UserStatusEnumType.php (Doctrine type).
  3. Manual Enum Creation:

    • Define a BackedEnum (e.g., Status: string).
    • Extend EnumType for the Doctrine type:
      class UserStatusEnumType extends EnumType {
          public const NAME = 'user_status';
          public static function getEnumsClass(): string { return Status::class; }
      }
      
    • Use in entities with #[ORM\Column(type: UserStatusEnumType::NAME)].
  4. Entity Integration:

    • Reference enum types in entity properties with type safety.
    • Add validation constraints (e.g., #[Assert\Choice(choices: Status::ALL)]).
    • Set defaults in options:
      #[ORM\Column(type: 'user_status', options: ['default' => Status::ACTIVE->value])]
      
  5. Database Migrations:

    • Run doctrine:migrations:diff and doctrine:migrations:migrate to create ENUM columns.
    • Example SQL output:
      ALTER TABLE user ADD status ENUM('active', 'inactive', 'banned') DEFAULT 'active' NOT NULL;
      

Workflows

  1. Development Workflow:

    • Generate enums with make:enum for rapid prototyping.
    • Extend enums with custom methods (e.g., isActive()).
    • Use IDE autocomplete for enum values in entities.
  2. Refactoring:

    • Prefer EnumType::NAME constants over string literals for refactoring safety.
    • Example:
      // Safe (refactoring-friendly)
      #[ORM\Column(type: UserStatusEnumType::NAME)]
      // Less safe (string literal)
      #[ORM\Column(type: 'user_status')]
      
  3. Testing:

    • Test enum logic in PHPUnit with assertions on enum values/methods.
    • Example:
      $this->assertTrue(DayOfWeek::SATURDAY->isWeekend());
      

Integration Tips

  1. Symfony Forms:

    • Use enums in form types with ChoiceType:
      $builder->add('status', ChoiceType::class, [
          'choices' => Status::cases(),
      ]);
      
  2. API Responses:

    • Serialize enums to strings or custom formats using value or custom methods:
      return ['status' => $user->getStatus()->value];
      
  3. Querying:

    • Filter entities by enum values:
      $activeUsers = $entityManager->getRepository(User::class)
          ->findBy(['status' => Status::ACTIVE]);
      
  4. DQL:

    • Use enum values directly in DQL queries:
      $query = $entityManager->createQuery(
          'SELECT u FROM App\Entity\User u WHERE u.status = :status'
      )->setParameter('status', Status::ACTIVE);
      

Gotchas and Tips

Pitfalls

  1. PHP 8.1 Requirement:

    • Ensure your project uses PHP 8.1+ for BackedEnum support.
    • Error: Class 'BackedEnum' not found if using PHP < 8.1.
  2. Enum Case Values:

    • MySQL ENUM columns are case-sensitive by default.
    • Ensure enum values match the database column exactly (e.g., 'active' vs 'Active').
    • Fix: Use consistent casing (e.g., lowercase) in enum definitions.
  3. Migration Conflicts:

    • If the database already has a column, migrations may fail if the ENUM values don’t match.
    • Fix: Drop and recreate the column or update the enum values manually.
  4. Circular Dependencies:

    • Avoid circular references between enums and entities (e.g., an enum referencing an entity).
    • Error: Cannot autowire service if Doctrine can’t resolve dependencies.
  5. Type Safety:

    • Forgetting to use ?Enum in entity properties can cause NULL issues.
    • Example:
      // Correct (nullable)
      private ?Status $status = null;
      // Incorrect (non-nullable)
      private Status $status; // Throws if NULL
      
  6. Custom Enum Methods:

    • Methods in enums are not automatically available in DQL or queries.
    • Workaround: Use CASE expressions in DQL or add static methods to the enum.

Debugging

  1. Enum Not Registered:

    • Check if the DoctrineEnumBundle is enabled in config/bundles.php.
    • Verify the EnumType class extends ArtFatal\DoctrineEnumBundle\Type\EnumType.
    • Clear cache after adding new enums:
      php bin/console cache:clear
      
  2. Database Errors:

    • Ensure the ENUM values in the database match the enum cases exactly.
    • Check the migration SQL for discrepancies:
      php bin/console doctrine:schema:update --dump-sql
      
  3. IDE Autocomplete:

    • If autocomplete doesn’t work, ensure the enum class is imported correctly.
    • Restart your IDE or run composer dump-autoload.
  4. Validation Errors:

    • Use #[Assert\Choice] to validate enum values in forms/entities.
    • Example:
      #[Assert\Choice(choices: Status::cases(), message: 'Invalid status.')]
      

Tips

  1. Naming Conventions:

    • Use PascalCase for enum classes (e.g., UserStatus).
    • Use snake_case for type constants (e.g., user_status).
    • Example:
      class UserStatusEnumType extends EnumType {
          public const NAME = 'user_status'; // snake_case
      }
      
  2. Reusable Enums:

    • Place custom enums in a dedicated namespace (e.g., App\Enum).
    • Example structure:
      src/
      ├── Enum/
      │   ├── User/
      │   │   └── Status.php
      │   └── Order/
      │       └── State.php
      └── Type/
          ├── Enum/
          │   ├── UserStatusEnumType.php
          │   └── OrderStateEnumType.php
      
  3. Enum Utilities:

    • Add static methods to enums for common operations:
      enum Status {
          case ACTIVE, INACTIVE;
          public static function isActive(Status $status): bool {
              return $status === self::ACTIVE;
          }
      }
      
  4. Performance:

    • MySQL ENUM columns are efficient for lookups but may impact performance with many values (>64).
    • Alternative: Use string columns with application-level validation if enums grow large.
  5. Testing Enums:

    • Test enum methods and values in isolation:
      public function testEnumMethods() {
          $this->assertEquals('Active', Status::ACTIVE->label());
          $this->
      
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
mehedimi/laravel-amp-mail
happones/laravel-vue-i18n-generator
jwerd/inertia-table
siberfx/flysystem-wasabi
hollyit/token-replace
ippanelcom/laravel-sdk
adachsoft/changelog-linter
adachsoft/collection
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel