Weave Code
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 Type Bundle Laravel Package

danaki/doctrine-enum-type-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the Bundle

    composer require danaki/doctrine-enum-type-bundle
    
  2. Configure Enums Create config/packages/doctrine_enum_type.yaml:

    danaki_doctrine_enum_type:
        types:
            App\Enum\YourEnum: ~
    

    Replace App\Enum\YourEnum with your actual enum class (must extend Acelaya\Enum\AbstractEnum).

  3. Define an Enum Example in app/Enum/Status.php:

    namespace App\Enum;
    
    use Acelaya\Enum\AbstractEnum;
    
    final class Status extends AbstractEnum
    {
        public const ACTIVE = 'active';
        public const INACTIVE = 'inactive';
    
        protected static function getValues(): array
        {
            return [
                self::ACTIVE,
                self::INACTIVE,
            ];
        }
    }
    
  4. Use in Doctrine Entities

    use App\Enum\Status;
    use Doctrine\ORM\Mapping as ORM;
    
    #[ORM\Entity]
    class User
    {
        #[ORM\Column(type: 'enum_gender')] // Default type; configure in YAML
        private Status $status;
    }
    
  5. Clear Cache

    php bin/console cache:clear
    

First Use Case: Migrating Legacy String Columns

Replace a string column (status: string) with an enum column:

# config/packages/doctrine_enum_type.yaml
danaki_doctrine_enum_type:
    types:
        App\Enum\Status: ~

Update the entity:

#[ORM\Column(type: 'enum_status')] // Custom type name (optional)
private Status $status;

Run migrations and update existing data via a migration or repository method.


Implementation Patterns

Workflow: Enum-Driven Development

  1. Define Enums Early Create enums for domain-specific values (e.g., OrderStatus, UserRole) before modeling entities. Example:

    namespace App\Enum;
    final class OrderStatus extends AbstractEnum {
        public const PENDING = 'pending';
        public const SHIPPED = 'shipped';
        public const CANCELLED = 'cancelled';
        // ...
    }
    
  2. Consistent Type Naming Use a naming convention for Doctrine types (e.g., enum_{EnumClassName}):

    danaki_doctrine_enum_type:
        types:
            enum_order_status: App\Enum\OrderStatus
    

    Reference in entities:

    #[ORM\Column(type: 'enum_order_status')]
    private OrderStatus $status;
    
  3. Integration with Forms Use EnumType from Symfony’s form component:

    use App\Enum\Status;
    use Symfony\Bridge\Doctrine\Form\Type\EntityType;
    
    $builder->add('status', EnumType::class, [
        'class' => Status::class,
        'choice_label' => fn($status) => ucfirst($status->value),
    ]);
    
  4. Querying with Enums Filter by enum values in repositories:

    $activeUsers = $entityManager->getRepository(User::class)
        ->createQueryBuilder('u')
        ->where('u.status = :status')
        ->setParameter('status', Status::ACTIVE)
        ->getQuery()
        ->getResult();
    
  5. API Responses Serialize enums to strings in JSON:

    #[Serializer\SerializedName('status')]
    public function getStatusValue(): string {
        return $this->status->value;
    }
    

Integration Tips

  • Database Compatibility Ensure your database supports ENUM types (MySQL) or use string with validation (PostgreSQL/SQLite). For PostgreSQL, configure a custom type in doctrine_enum_type.yaml:

    danaki_doctrine_enum_type:
        types:
            App\Enum\Status:
                type: string
                length: 20
    
  • Validation Combine with Symfony’s validator for runtime checks:

    use Symfony\Component\Validator\Constraints as Assert;
    
    #[ORM\Column(type: 'enum_status')]
    #[Assert\Type(type: 'App\Enum\Status')]
    private Status $status;
    
  • Testing Mock enums in unit tests:

    $this->entity->setStatus(Status::ACTIVE);
    $this->assertEquals(Status::ACTIVE, $this->entity->getStatus());
    

Gotchas and Tips

Pitfalls

  1. Cache Dependencies

    • Issue: "Unknown column type" errors persist after configuration changes.
    • Fix: Clear all caches:
      php bin/console cache:clear
      rm -rf var/cache/*
      
  2. Enum Class Requirements

    • Issue: Enums must extend Acelaya\Enum\AbstractEnum and implement getValues().
    • Fix: Use the provided abstract class or implement the interface:
      use Acelaya\Enum\AbstractEnum;
      
      final class Status extends AbstractEnum { ... }
      
  3. Database-Specific Quirks

    • MySQL: Uses native ENUM type (limited to 64 values).
    • PostgreSQL/SQLite: Falls back to string; ensure length constraints in YAML:
      danaki_doctrine_enum_type:
          types:
              App\Enum\Status:
                  type: string
                  length: 20
      
  4. Case Sensitivity

    • Issue: Enum values are case-sensitive in queries.
    • Fix: Normalize values (e.g., strtolower()) or use constants consistently.
  5. Migration Order

    • Issue: Adding an enum column to an existing table may fail if data doesn’t match enum values.
    • Fix: Migrate data first or use nullable: true temporarily.

Debugging

  1. Check Configuration Validate doctrine_enum_type.yaml syntax and enum class paths. Use:

    php bin/console debug:config danaki_doctrine_enum_type
    
  2. Doctrine Events Listen for loadClassMetadata to debug type mapping:

    $eventManager->addEventListener(ORM\Events::loadClassMetadata, function (ORM\Event\LoadClassMetadataEvent $event) {
        if ($event->getClassMetadata()->hasField('status')) {
            dump($event->getClassMetadata()->getTypeOfField('status'));
        }
    });
    
  3. SQL Logging Enable Doctrine SQL logging to verify generated queries:

    # config/packages/dev/doctrine.yaml
    doctrine:
        dbal:
            logging: true
            logging_format: '%%sql%% %%params%%'
    

Extension Points

  1. Custom Type Mappings Extend the bundle’s configuration for non-standard types:

    danaki_doctrine_enum_type:
        types:
            App\Enum\Priority:
                type: integer
                values:
                    LOW: 1
                    HIGH: 2
    
  2. Dynamic Enum Registration Register enums programmatically in a compiler pass:

    use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
    use Symfony\Component\DependencyInjection\ContainerBuilder;
    
    class EnumCompilerPass implements CompilerPassInterface {
        public function process(ContainerBuilder $container) {
            $definition = $container->findDefinition('danaki_doctrine_enum_type.type_registry');
            $definition->addMethodCall('addType', ['App\Enum\DynamicEnum', []]);
        }
    }
    
  3. Symfony UX Autocomplete Integrate with Symfony UX for dynamic enum selection:

    use Symfony\UX\Autocomplete\Attribute\AutocompleteSource;
    
    #[AutocompleteSource('status_autocomplete')]
    public function getStatusChoices(): array {
        return array_map(fn($status) => ['value' => $status, 'label' => ucfirst($status)], Status::getValues());
    }
    

Pro Tips

  • Enum Utilities Add helper methods to enums for common operations:

    final class Status extends AbstractEnum {
        public static function isActive(string $value): bool {
            return $value === self::ACTIVE;
        }
    }
    
  • API Platform Integration Use @ApiProperty to customize OpenAPI schema:

    use ApiPlatform\Metadata\ApiProperty;
    
    #[ApiProperty(enum: [Status::ACTIVE, Status::INACTIVE])]
    private Status $status;
    
  • Performance For large datasets, index enum columns:

    #[ORM\Column(type: 'enum_status')]
    #[ORM\Index]
    private Status $status;
    
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.
cadot.eu/make
besmartand-pro/php-quality-config
sentix/ai-chatbot
codifyo/ts-generator-bundle
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky