Skip to content

vikingsurfeur/enum_doctrine_type

Repository files navigation

Doctrine Enum Type Handler

Une implémentation robuste pour utiliser les enums PHP 8.1+ comme types personnalisés dans Doctrine ORM avec PostgreSQL.

📋 Présentation

Ce projet fournit un ensemble de classes permettant d'utiliser les enums PHP comme types natifs dans PostgreSQL via Doctrine. La solution garantit l'intégrité des données en créant des types enum personnalisés dans PostgreSQL qui correspondent directement aux valeurs de vos enums PHP.

Caractéristiques

  • ✅ Support complet des backed enums et des enums classiques
  • ✅ Validation côté base de données via des contraintes PostgreSQL natives
  • ✅ Conversion automatique entre les représentations PHP et SQL
  • ✅ Architecture extensible suivant les principes SOLID
  • ✅ Tests unitaires et d'intégration complets

🚀 Installation

Prérequis

  • PHP 8.1+
  • Symfony 6.0+
  • Doctrine ORM
  • PostgreSQL

Configuration

  1. Clonez ce dépôt ou copiez les fichiers dans votre projet

  2. Enregistrez les types personnalisés dans le fichier de configuration Doctrine :

# config/packages/doctrine.yaml
doctrine:
    dbal:
        types:
            task_priority_enum: App\Doctrine\Type\TaskPriorityEnumType
  1. Exécutez les migrations pour créer les types enum dans PostgreSQL

🔧 Utilisation

1. Créer un Enum PHP

<?php
declare(strict_types=1);

namespace App\Enum;

enum TaskPriorityEnum: string
{
    case LOW = 'basse';
    case MEDIUM = 'normale';
    case HIGH = 'haute';
    case CRITICAL = 'critique';
}

2. Créer un Type Doctrine correspondant

<?php
declare(strict_types=1);

namespace App\Doctrine\Type;

use App\Enum\TaskPriorityEnum;

class TaskPriorityEnumType extends AbstractEnumType
{
    public const TYPE_NAME = 'task_priority_enum';
    
    public static function getTypeName(): string
    {
        return self::TYPE_NAME;
    }
    
    protected static function getEnumClass(): string
    {
        return TaskPriorityEnum::class;
    }
}

3. Utiliser le type dans une entité

<?php
namespace App\Entity;

use App\Doctrine\Type\TaskPriorityEnumType;
use App\Enum\TaskPriorityEnum;
use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity]
class Task
{
    #[ORM\Column(type: TaskPriorityEnumType::TYPE_NAME)]
    private ?TaskPriorityEnum $priority = null;
    
    public function getPriority(): ?TaskPriorityEnum
    {
        return $this->priority;
    }
    
    public function setPriority(TaskPriorityEnum $priority): self
    {
        $this->priority = $priority;
        return $this;
    }
}

4. Créer une migration

La migration doit créer le type enum PostgreSQL avant de créer les tables qui l'utilisent :

<?php
declare(strict_types=1);

namespace DoctrineMigrations;

use App\Doctrine\Type\TaskPriorityEnumType;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;

final class Version20250319040536 extends AbstractMigration
{
    public function getDescription(): string
    {
        return 'Task / TaskPriorityEnumType';
    }
    
    public function up(Schema $schema): void
    {
        // Créer d'abord le type enum
        $this->addSql(TaskPriorityEnumType::getCreateTypeSQL());
        
        // Puis créer la table qui l'utilise
        $this->addSql('CREATE TABLE task (
            id INT GENERATED BY DEFAULT AS IDENTITY NOT NULL, 
            name VARCHAR(255) NOT NULL, 
            created_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, 
            priority task_priority_enum NOT NULL, 
            PRIMARY KEY(id)
        )');
    }
    
    public function down(Schema $schema): void
    {
        $this->addSql('DROP TABLE task');
        $this->addSql(TaskPriorityEnumType::getDropTypeSQL());
    }
}

💻 Fonctionnement interne

Architecture

Le système repose sur trois composants principaux :

  1. AbstractEnumType : Classe abstraite gérant la conversion entre PHP et SQL
  2. EnumTypeHelper : Classe utilitaire pour générer le SQL nécessaire aux types enum PostgreSQL
  3. Types concrets (ex: TaskPriorityEnumType) : Implémentations spécifiques pour chaque enum

Flux de données

  1. En lecture, les valeurs de la base de données sont converties en instances d'enum PHP
  2. En écriture, les instances d'enum PHP sont converties en chaînes pour la base de données
  3. PostgreSQL valide que les valeurs correspondent bien aux valeurs autorisées par le type enum

🧪 Tests

Le projet inclut des tests unitaires et d'intégration pour garantir le bon fonctionnement.

Exécution des tests

# Installer les dépendances de développement
composer require --dev phpunit/phpunit symfony/test-pack

# Exécuter tous les tests
./vendor/bin/phpunit

# Exécuter uniquement les tests unitaires
./vendor/bin/phpunit --testsuite Unit

# Exécuter uniquement les tests d'intégration
./vendor/bin/phpunit --testsuite Integration

🤝 Contribution

Les contributions sont les bienvenues ! N'hésitez pas à ouvrir une issue ou une pull request.

Principes de développement

Ce projet suit les principes SOLID et les bonnes pratiques de Clean Code :

  • Single Responsibility : Chaque classe a une responsabilité unique
  • Open/Closed : Le système est ouvert à l'extension mais fermé à la modification
  • Liskov Substitution : Les sous-types sont substituables à leurs types de base
  • Interface Segregation : Les interfaces sont spécifiques à leurs clients
  • Dependency Inversion : Dépendance vers les abstractions, non les implémentations

📄 Licence

Ce projet est sous licence MIT. Voir le fichier LICENSE pour plus d'informations.

About

Short example to show how create an doctrine enum type

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published