andydefer / laravel-addresses
Laravel package providing polymorphic addresses with Repository pattern, DTOs, Enums, and Value Objects.
Requires
- php: ^8.2
- andydefer/laravel-repository: ^2.8.6
- andydefer/php-vo: ^0.9.3
- laravel/framework: ^12.0|^13.0|^14.0|^15.0
Requires (Dev)
- barryvdh/laravel-ide-helper: ^3.6
- composer/composer: ^2.0
- larastan/larastan: ^3.8
- laravel/pint: ^1.26
- orchestra/testbench: ^10.8
- phpunit/phpunit: ^12.5
- rector/rector: *
- symfony/var-dumper: ^7.0
- vimeo/psalm: ^6.14
README
Gestion d'adresses polymorphiques pour applications Laravel
Un package Laravel complet pour gérer des adresses polymorphiques avec le pattern Repository, des DTOs, des Value Objects et une gestion des adresses principales.
✨ Fonctionnalités
- ✅ Adresses polymorphiques - Attachez des adresses à n'importe quel modèle Eloquent
- ✅ Types d'adresses multiples - PRINCIPALE, FACTURATION, LIVRAISON, PROFESSIONNELLE, AUTRE
- ✅ Gestion de l'adresse principale - Définissez et récupérez l'adresse principale
- ✅ Pattern Repository - Séparation propre de la logique d'accès aux données
- ✅ Support des DTOs - Objets de transfert de données typés
- ✅ Value Objects - Pays, Code postal, Coordonnées, Date/Heure
- ✅ Support des métadonnées - Stockez des données supplémentaires au format JSON
- ✅ Suppression douce - Suppression sécurisée avec possibilité de restauration
- ✅ Filtrage avancé - Filtrez par type, ville, pays, code postal
- ✅ Mises à jour brutes - Mettez à jour avec support des valeurs NULL
- ✅ Tests complets - Couverture complète des tests d'intégration
📦 Installation
Installez le package via Composer :
composer require andydefer/laravel-addresses
Publier les migrations
php artisan vendor:publish --tag=Addresses-migrations
Exécuter les migrations
php artisan migrate
⚙️ Configuration
Le package est automatiquement découvert par Laravel. Aucune configuration supplémentaire n'est requise.
Si vous devez personnaliser le Service Provider, ajoutez-le manuellement dans config/app.php :
'providers' => [ // ... AndyDefer\LaravelAddresses\AddressesServiceProvider::class, ],
📖 Utilisation
Ajouter une adresse
use AndyDefer\LaravelAddresses\Services\AddressService; use AndyDefer\LaravelAddresses\Records\AddressRecord; use AndyDefer\LaravelAddresses\Enums\AddressType; use AndyDefer\PhpVo\Enums\Country; use AndyDefer\PhpVo\ValueObjects\PostalCodeVO; class UserController extends Controller { public function store(AddressService $addressService) { $user = User::find(1); $record = AddressRecord::from([ 'street' => '123 Rue Principale', 'city' => 'Paris', 'country' => Country::FR, 'postal_code' => PostalCodeVO::from('75001'), 'address_type' => AddressType::PRIMARY, ]); $address = $addressService->add($user, $record); return $address; } }
Récupérer des adresses
Toutes les adresses
$addresses = $addressService->all($user);
Par type
$billingAddresses = $addressService->byType($user, AddressType::BILLING);
Adresse principale
$primary = $addressService->primary($user);
Trouver par ID
$address = $addressService->find($addressId);
Compter les adresses
$count = $addressService->count($user);
Vérifier si un type existe
$hasShipping = $addressService->hasType($user, AddressType::SHIPPING);
Mettre à jour une adresse
Mise à jour avec un Record (DTO)
$updateRecord = AddressRecord::from([ 'street' => '456 Nouvelle Rue', 'city' => 'Lyon', 'country' => Country::FR, 'postal_code' => PostalCodeVO::from('69001'), ]); $updated = $addressService->update($addressId, $updateRecord);
Mise à jour avec des données brutes (incluant NULL)
Utilisez updateRaw() lorsque vous devez définir des champs à NULL dans la base de données :
// Définir les métadonnées à NULL $updated = $addressService->updateRaw($addressId, [ 'metadata' => null, ]); // Définir les coordonnées à NULL $updated = $addressService->updateRaw($addressId, [ 'geo_coordinates' => null, ]); // Mise à jour partielle $updated = $addressService->updateRaw($addressId, [ 'street' => 'Rue Mise à Jour', 'address_type' => AddressType::BILLING->value, ]);
Supprimer une adresse
$deleted = $addressService->delete($addressId); // Retourne true si supprimé, false sinon
Gestion de l'adresse principale
Définir une adresse comme principale
$addressService->setPrimary($user, $addressId);
Note : Cela rétrogradera automatiquement l'ancienne adresse principale en
AddressType::OTHER.
Récupérer l'adresse principale
$primary = $addressService->primary($user);
🔍 Filtrer les adresses
Utilisez AddressFilterRecord pour un filtrage avancé :
use AndyDefer\LaravelAddresses\Records\AddressFilterRecord; use AndyDefer\Repository\Records\FindByRecord; $filter = new AddressFilterRecord( addressable_type: 'App\Models\User', addressable_id: 1, address_type: AddressType::BILLING, city: 'Paris', country: Country::FR, postal_code: '75001' ); $findByRecord = new FindByRecord( filters: $filter, limit: 10, offset: 0, order_by: 'created_at', order_direction: 'desc' ); $addresses = $addressRepository->findBy($findByRecord);
📚 Référence de l'API
AddressService
| Méthode | Description | Retourne |
|---|---|---|
add(Model $addressable, AddressRecord $record) |
Créer une nouvelle adresse | Model |
update(int $addressId, AddressRecord $record) |
Mettre à jour une adresse avec DTO | Model |
updateRaw(int $addressId, array $data) |
Mettre à jour avec données brutes (NULL) | Model |
delete(int $addressId) |
Supprimer une adresse | bool |
all(Model $addressable) |
Récupérer toutes les adresses | Collection |
byType(Model $addressable, AddressType $type) |
Récupérer les adresses par type | Collection |
primary(Model $addressable) |
Récupérer l'adresse principale | ?Model |
setPrimary(Model $addressable, int $addressId) |
Définir l'adresse principale | void |
find(int $addressId) |
Trouver une adresse par ID | ?Model |
count(Model $addressable) |
Compter les adresses | int |
hasType(Model $addressable, AddressType $type) |
Vérifier si un type existe | bool |
AddressType Enum
| Cas | Valeur |
|---|---|
AddressType::PRIMARY |
'primary' |
AddressType::BILLING |
'billing' |
AddressType::SHIPPING |
'shipping' |
AddressType::WORK |
'work' |
AddressType::OTHER |
'other' |
🎯 Value Objects
Le package supporte les Value Objects suivants de andydefer/php-vo :
| Value Object | Description | Exemple |
|---|---|---|
Country |
Enum des pays | Country::FR, Country::US |
PostalCodeVO |
Code postal | PostalCodeVO::from('75001') |
CoordinatesVO |
Coordonnées géographiques | CoordinatesVO::from(['latitude' => 48.8566, 'longitude' => 2.3522]) |
DateTimeVO |
Date/heure | DateTimeVO::from('2024-01-01 12:00:00') |
Accesseurs dans le modèle Address
Le modèle Address fournit des accesseurs pratiques :
$address = Address::find(1); // Accès sous forme de Value Objects $postalCode = $address->postalCode; // PostalCodeVO $coordinates = $address->coordinates; // CoordinatesVO $metadata = $address->metadata; // StrictDataObject $createdAt = $address->createdAt; // DateTimeVO $updatedAt = $address->updatedAt; // DateTimeVO $deletedAt = $address->deletedAt; // DateTimeVO
🧪 Tests
Exécuter les tests
composer test
Exécuter uniquement les tests unitaires
composer test-unit
Exécuter uniquement les tests d'intégration
composer test-integration
Configuration des tests
Le package utilise orchestra/testbench pour les tests d'intégration avec une base de données SQLite en mémoire.
📝 Schéma de la base de données
CREATE TABLE addresses ( id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, addressable_type VARCHAR(255) NOT NULL, addressable_id BIGINT UNSIGNED NOT NULL, street VARCHAR(255) NULL, city VARCHAR(255) NULL, country VARCHAR(2) NULL, postal_code VARCHAR(20) NULL, geo_coordinates JSON NULL, address_type VARCHAR(20) NULL, metadata JSON NULL, created_at TIMESTAMP NULL, updated_at TIMESTAMP NULL, deleted_at TIMESTAMP NULL, INDEX idx_addressable (addressable_type, addressable_id), INDEX idx_address_type (addressable_type, addressable_id, address_type), INDEX idx_country (country), INDEX idx_postal_code (postal_code) );
🔧 Développement
Style de code
./vendor/bin/pint
Analyse statique
./vendor/bin/phpstan analyse ./vendor/bin/psalm
📄 Journal des modifications
Veuillez consulter le CHANGELOG pour plus d'informations sur les modifications récentes.
🤝 Contribuer
Veuillez consulter CONTRIBUTING pour plus de détails.
Flux de développement
- Forkez le dépôt
- Créez une branche de fonctionnalité (
git checkout -b feature/amazing-feature) - Apportez vos modifications
- Exécutez les tests (
composer test) - Committez vos modifications (
git commit -m 'Ajouter une fonctionnalité géniale') - Poussez vers la branche (
git push origin feature/amazing-feature) - Ouvrez une Pull Request
📦 Dépendances
andydefer/php-vo- Value Objectsandydefer/laravel-repository- Implémentation du pattern Repository
👨💻 Auteur
Andy Kani
- GitHub: @andydefer
- Email: andykanidimbu@gmail.com
📄 Licence
La licence MIT (MIT). Veuillez consulter le Fichier de licence pour plus d'informations.
⭐ Support
Si vous trouvez ce package utile, n'hésitez pas à lui donner une ⭐ sur GitHub !