Download the PHP package andydefer/laravel-rattachments without Composer
On this page you can find all versions of the php package andydefer/laravel-rattachments. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download andydefer/laravel-rattachments
More information about andydefer/laravel-rattachments
Files in andydefer/laravel-rattachments
Package laravel-rattachments
Short Description Polymorphic attachment system for Laravel with double polymorphic relationships, roles, and metadata support.
License MIT
Informations about the package laravel-rattachments
Laravel Rattachments
Un système de rattachement polymorphique double pour applications Laravel
Un package Laravel complet pour gérer des relations polymorphiques doubles entre n'importe quels modèles Eloquent, avec des rôles contextuels, des métadonnées, un système de contraintes avancé et des hooks de cycle de vie.
📋 Table des matières
- Problématique et solution
- Fonctionnalités
- Installation
- Concept fondamental
- Double polymorphisme
- Les contraintes
- Rôles contextuels
- Résolution dynamique des rôles
- Système de hooks
- Utilisation avec le service
- Utilisation avec le trait
- Exemples concrets
- Cas d'usage
- Règles du système
- Inspection CLI
- Dépendances
- Licence
🎯 Problématique et solution
Le problème
Dans les applications modernes, les relations entre entités sont rarement simples et unidirectionnelles. Les besoins courants incluent :
- Relations sociales : Amitiés, abonnements, blocages
- Relations professionnelles : Médecins dans des hôpitaux, employés dans des entreprises
- Relations de contenu : Tags sur des articles, catégories sur des produits
- Relations contextuelles : Rôles différents selon le contexte
Les solutions traditionnelles (tables de liaison spécifiques) conduisent à :
Le résultat :
- ✅ Multiples tables
- ❌ Code répétitif
- ❌ Relations complexes
- ❌ Pas de polymorphisme
- ❌ Pas de rôles contextuels
- ❌ Pas de métadonnées
La solution
Laravel Rattachments propose une approche élégante : une seule table polymorphique pour gérer tous les types de relations.
Le principe :
Pourquoi c'est révolutionnaire ?
- ✅ Une table pour toutes les relations
- ✅ Polymorphique : n'importe quel modèle avec n'importe quel autre
- ✅ Rôles contextuels : chaque modèle définit ses propres rôles
- ✅ Contraintes avancées : autorisation, unicité, interdiction
- ✅ Métadonnées : stockez des données supplémentaires
- ✅ Hooks de cycle de vie : intervenez avant/après chaque opération
- ✅ API fluide : utilisez vos modèles comme des objets métier
✨ Fonctionnalités
- ✅ Double polymorphisme - Rattachez n'importe quel modèle à n'importe quel autre modèle
- ✅ Rôles contextuels - Chaque modèle définit ses propres rôles via des enums
- ✅ Système de contraintes complet - Autorisation, unicité et interdiction
- ✅ Validation centralisée -
ConstraintValidatorpour une validation cohérente - ✅ Résolution dynamique des rôles - Pas d'enum global, résolution basée sur le contexte
- ✅ Métadonnées flexibles - Stockez des données supplémentaires au format JSON
- ✅ Hooks de cycle de vie -
beforeAttach,afterAttach,beforeDetach,afterDetach, etc. - ✅ Trait HasRattachments - API fluide directement dans vos modèles
- ✅ Filtrage avancé - Par type, rôle, ou combinaison
- ✅ Opérations en masse - Rattachement et détachement multiples
- ✅ Synchronisation - Synchronisez tous les rattachements d'un modèle en une seule opération
- ✅ Pagination - Récupérez les résultats paginés
- ✅ Inspection CLI - Directive
rattachments:inspectpour analyser les contraintes - ✅ Détection de circularité CLI - Directive
rattachments:circularitypour détecter les relations circulaires - ✅ Contraintes uniques granulaires - Un seul attachement par type ET rôle
- ✅ UnknownRole - Rétrocompatibilité pour les rôles supprimés
- ✅ Typage strict - Utilisation de
Model&RattachmentInterfacepour la sécurité des types - ✅ Détection de circularité - Empêche les relations circulaires
- ✅ Auto-attachement - Empêche un modèle de s'attacher à lui-même
- ✅ Tests complets - Couverture complète des tests d'intégration
🚀 Installation
Publier les migrations
Exécuter les migrations
🎯 Concept fondamental
Qu'est-ce qu'un rattachement ?
Un rattachement est une relation polymorphique double entre deux modèles Eloquent. Il est représenté par un enregistrement dans la table rattachments qui stocke :
- Le modèle source (
rattachable) - Celui qui attache - Le modèle cible (
target) - Celui qui est attaché - Un rôle - Définit la nature de la relation
- Des métadonnées - Données supplémentaires au format JSON
Exemple concret
🔄 Double polymorphisme
Qu'est-ce que le double polymorphisme ?
Le package permet de rattacher n'importe quel modèle à n'importe quel autre modèle, dans les deux sens :
Pourquoi c'est puissant ?
| Approche traditionnelle | Laravel Rattachments |
|---|---|
User::friends() |
$user->getTargetsByType(User::class) |
User::follows() |
$user->getTargetsByType(User::class, FollowRole::FOLLOWER) |
User::blocks() |
$user->getTargetsByType(User::class, BlockRole::BLOCKED) |
Post::tags() |
$post->getTargetsByType(Tag::class) |
Doctor::hospitals() |
$doctor->getTargetsByType(Hospital::class) |
Une seule méthode, des résultats infinis !
🔒 Les contraintes
L'interface RattachmentInterface permet à vos modèles de définir trois types de contraintes.
1. Cibles autorisées (allowedTargets)
Définit quels modèles peuvent être attachés et avec quels rôles.
2. Cibles uniques granulaires (uniqueTargets)
Limite un modèle à un seul rattachement par type et/ou rôle.
Exemple concret :
3. Cibles interdites (disallowedTargets)
Bloque des cibles ou des rôles spécifiques (priorité maximale).
🏷️ Rôles contextuels
Pourquoi des rôles contextuels ?
Dans une application, le même terme ("admin") peut avoir des significations différentes :
- Un administrateur d'hôpital ≠ administrateur de site
- Un médecin peut avoir des rôles différents selon l'hôpital
Les rôles contextuels permettent de définir des enums spécifiques à chaque contexte.
🔄 Résolution dynamique des rôles
Comment ça fonctionne ?
Le package résout automatiquement le bon enum en fonction du contexte :
Avantages
- ✅ Pas d'enum global - Chaque modèle définit ses propres rôles
- ✅ Contextuel - Le même nom a des significations différentes selon le contexte
- ✅ Rétrocompatible - Les rôles supprimés retournent
UnknownRole - ✅ Performant - Instanciation directe, pas de requête SQL
UnknownRole
Si un rôle n'est plus autorisé par les contraintes actuelles, l'accesseur retourne une instance de UnknownRole :
🔌 Système de hooks
Le package expose un système de hooks permettant d'intervenir à chaque étape du cycle de vie d'un attachement.
Interface AttachmentHookInterface
Tous les modèles implémentant RattachmentInterface héritent de AttachmentHookInterface et peuvent surcharger les méthodes suivantes :
| Hook | Déclenchement |
|---|---|
beforeAttach() |
Avant la création d'un attachement |
afterAttach() |
Après la création d'un attachement |
beforeDetach() |
Avant la suppression d'un attachement |
afterDetach() |
Après la suppression d'un attachement |
beforeUpdateRole() |
Avant la mise à jour d'un rôle |
afterUpdateRole() |
Après la mise à jour d'un rôle |
beforeUpdateMetadata() |
Avant la mise à jour des métadonnées |
afterUpdateMetadata() |
Après la mise à jour des métadonnées |
beforeDetachAll() |
Avant la suppression de tous les attachements |
afterDetachAll() |
Après la suppression de tous les attachements |
Position du modèle
Chaque hook reçoit un paramètre HookPosition qui indique si le modèle est le rattachable (celui qui attache) ou le target (celui qui est attaché) :
Exemple d'implémentation
📖 Utilisation avec le service
Injection du service
Créer un rattachement
Rattachement multiple
Supprimer un rattachement
Vérifier l'existence
Récupérer les rattachements
Pagination
Compter
Mettre à jour
Synchroniser
Rôles distincts
Attachements entre types
📖 Utilisation avec le trait
Le trait HasRattachments offre une API fluide directement sur vos modèles.
Ajouter le trait
API fluide
Récupérer dans les deux sens
Compter les relations
Méthodes métier explicites
Créez des méthodes métier pour une sémantique claire :
💡 Exemples concrets
Exemple 1 : Réseau social - Amitiés
Exemple 2 : Réseau social - Abonnements
Exemple 3 : Gestion de contenu - Tags
Exemple 4 : Relations professionnelles avec hooks
🎯 Cas d'usage
Réseau social
| Relation | Rattachable → Target | Rôle |
|---|---|---|
| Amitié | User → User | FriendRole::FRIEND |
| Abonnement | User → User | FollowRole::FOLLOWER |
| Blocage | User → User | BlockRole::BLOCKED |
| Invitation | Group → User | InviteRole::PENDING |
| Acceptation | User → Group | InviteRole::ACCEPTED |
Santé
| Relation | Rattachable → Target | Rôle |
|---|---|---|
| Médecin → Hôpital | Doctor → Hospital | HospitalRole::DOCTOR |
| Patient → Médecin | Patient → Doctor | PatientRole::PATIENT |
| Spécialité → Médecin | Specialty → Doctor | SpecialtyRole::PRIMARY |
| Ordonnance → Patient | Prescription → Patient | PrescriptionRole::ACTIVE |
Contenu
| Relation | Rattachable → Target | Rôle |
|---|---|---|
| Article → Tag | Post → Tag | TagRole::PRIMARY |
| Article → Catégorie | Post → Category | CategoryRole::MAIN |
| Article → Auteur | Post → User | AuthorRole::AUTHOR |
| Commentaire → Article | Comment → Post | CommentRole::APPROVED |
Entreprise
| Relation | Rattachable → Target | Rôle |
|---|---|---|
| Employé → Entreprise | Employee → Company | EmployeeRole::MANAGER |
| Employé → Projet | Employee → Project | ProjectRole::LEAD |
| Projet → Client | Project → Client | ClientRole::ACTIVE |
| Tâche → Employé | Task → Employee | TaskRole::ASSIGNED |
📋 Règles du système
Règle 1 : Toute relation est orientée
Règle 2 : Les modèles doivent implémenter l'interface
Règle 3 : Le rôle est obligatoire
Règle 4 : disallowedTargets a priorité sur allowedTargets
Résultat :
Règle 5 : Circularité - INTERDITE
Deux modèles ne peuvent pas s'autoriser mutuellement avec le même rôle.
Exceptions :
- ✅ Les relations entre modèles de même type (ex:
User → User) ne sont pas concernées
Règle 6 : Auto-attachement - INTERDIT
Règle 7 : Ordre de validation
Règle 8 : Résumé des contraintes
| Contrainte | Priorité |
|---|---|
disallowedTargets |
🔴 Maximale |
uniqueTargets |
🟡 Élevée |
allowedTargets |
🟢 Normale |
Règle 9 : Bonnes pratiques
Une direction unique
Interdire la mauvaise direction
Ne pas contredire allowedTargets
Symétrie explicite
🔍 Inspection CLI
Commandes
Exemple de sortie - rattachments:inspect
Exemple de sortie - rattachments:inspect avec --ignore-missing
Exemple de sortie - rattachments:circularity
Sans --ignore-skipped (affichage complet)
Avec --ignore-skipped (sortie épurée)
Options des commandes
rattachments:inspect
| Option | Description |
|---|---|
--constraints |
Affiche uniquement les contraintes (allowedTargets, uniqueTargets, disallowedTargets) |
--connections |
Affiche uniquement les connexions existantes en base |
--ignore-missing |
Masque les suggestions de relations manquantes |
rattachments:circularity
| Option | Description |
|---|---|
--ignore-skipped |
Masque les éléments "Skipped" (même classe, n'implémente pas l'interface) pour une sortie plus épurée |
Alias disponibles
| Commande | Alias | Description |
|---|---|---|
rattachments:inspect |
ri |
Inspection des contraintes et connexions |
rattachments:circularity |
rc |
Détection de circularité |
rattachments:circularity |
rattachments:check-circularity |
Détection de circularité (nom long) |
📦 Dépendances
andydefer/domain-structures- Structures de domaine (Value Objects, Records)andydefer/laravel-repository- Pattern Repositoryandydefer/laravel-directive- Framework CLIandydefer/php-services- Services PHP
📄 Licence
MIT © Andy Defer
Construit avec ❤️ pour la communauté Laravel
All versions of laravel-rattachments with dependencies
laravel/framework Version ^12.0|^13.0|^14.0|^15.0
andydefer/laravel-directive Version ^3.67.16
andydefer/laravel-repository Version ^2.17.36