andydefer/laravel-likes
Composer 安装命令:
composer require andydefer/laravel-likes
包简介
Laravel package providing polymorphic reactions (like, love, haha, wow, sad, angry) with Repository pattern, DTOs, Enums, and Value Objects.
README 文档
README
Système de réactions polymorphiques pour applications Laravel
Un package Laravel complet pour gérer des réactions polymorphiques (likes, loves, haha, wow, sad, angry) avec le pattern Repository, des DTOs, des Value Objects et un système de toggle intelligent.
📋 Table des matières
- Fonctionnalités
- Prérequis
- Installation
- Configuration
- Utilisation
- Types de réactions
- Référence de l'API
- Value Objects
- Structure de la base de données
- Tests
- Contribuer
- Licence
✨ Fonctionnalités
- ✅ Double polymorphisme - Réagissez à n'importe quel modèle avec n'importe quel utilisateur
- ✅ 6 types de réactions - LIKE, LOVE, HAHA, WOW, SAD, ANGRY avec emojis
- ✅ Toggle intelligent - Changez de réaction en un seul appel
- ✅ Filtrage temporel - Récupérez les réactions après une date donnée
- ✅ 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 - DateTime, Métadonnées
- ✅ 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, par auteur, par objet
- ✅ Tests complets - Couverture complète des tests d'intégration
🚀 Prérequis
- PHP 8.2 ou supérieur
- Laravel 12.0, 13.0, 14.0 ou 15.0
📦 Installation
Installez le package via Composer :
composer require andydefer/laravel-likes
Publier les migrations
php artisan vendor:publish --tag=Likes-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\LaravelLikes\LikesServiceProvider::class, ],
📖 Utilisation
Toggle une réaction
La méthode toggle() est la plus polyvalente. Elle permet de :
- Ajouter une réaction si elle n'existe pas
- Changer de type de réaction si elle existe déjà
- Supprimer la réaction si le même type est utilisé
use AndyDefer\LaravelLikes\Services\LikeService; use AndyDefer\LaravelLikes\Enums\LikeType; class PostController extends Controller { public function react(LikeService $likeService, Post $post) { $user = auth()->user(); // Toggle un like (👍) $liked = $likeService->toggle($user, $post, LikeType::LIKE); // Toggle un love (❤️) $loved = $likeService->toggle($user, $post, LikeType::LOVE); // Toggle un haha (😂) $haha = $likeService->toggle($user, $post, LikeType::HAHA); return response()->json([ 'reacted' => $liked, 'type' => $liked ? LikeType::LIKE->value : null, 'emoji' => $liked ? LikeType::LIKE->getEmoji() : null, ]); } }
Ajouter un like
// Ajoute un like (👍) - Lève une exception si déjà liké $likeService->like($user, $post);
Supprimer un like
// Supprime un like - Lève une exception si non liké $likeService->unlike($user, $post);
Vérifier une réaction
// Vérifier si l'utilisateur a réagi $hasLiked = $likeService->hasLiked($user, $post);
Compter les réactions
// Compter toutes les réactions d'un objet $total = $likeService->countLikes($post); // Compter par type $likes = $likeService->countLikesByType($post, LikeType::LIKE); $loves = $likeService->countLikesByType($post, LikeType::LOVE); $hahas = $likeService->countLikesByType($post, LikeType::HAHA);
Récupérer les réactions
// Récupérer tous les likeurs d'un objet $likers = $likeService->getLikers($post); // Récupérer les likeurs par type $likersByType = $likeService->getLikersByType($post, LikeType::LOVE); // Récupérer toutes les réactions d'un utilisateur $userLikes = $likeService->getLikerLikes($user); // Récupérer les réactions d'un utilisateur par type $userLoves = $likeService->getLikerLikesByType($user, LikeType::LOVE);
Filtrer par date
use AndyDefer\PhpVo\ValueObjects\DateTimeVO; $date = DateTimeVO::from('2024-01-01 00:00:00'); // Récupérer toutes les réactions mises à jour après une date $recentLikes = $likeService->getLikesUpdatedAfter($date); // Récupérer les réactions d'un utilisateur après une date $userRecentLikes = $likeService->getLikerLikesUpdatedAfter($user, $date); // Récupérer les réactions d'un objet après une date $postRecentLikes = $likeService->getLikesForLikeableUpdatedAfter($post, $date);
🏷️ Types de réactions
| Type | Valeur | Emoji | Label |
|---|---|---|---|
LikeType::LIKE |
'like' |
👍 | J'aime |
LikeType::LOVE |
'love' |
❤️ | J'adore |
LikeType::HAHA |
'haha' |
😂 | Haha |
LikeType::WOW |
'wow' |
😮 | Wow |
LikeType::SAD |
'sad' |
😢 | Triste |
LikeType::ANGRY |
'angry' |
😡 | En colère |
Utilisation des émojis
use AndyDefer\LaravelLikes\Enums\LikeType; $type = LikeType::LOVE; echo $type->getEmoji(); // ❤️ echo $type->getLabel(); // J'adore
📚 Référence de l'API
LikeService
| Méthode | Description | Retourne |
|---|---|---|
toggle(Model $liker, Model $likeable, LikeType $type = LikeType::LIKE) |
Toggle une réaction (ajoute/change/supprime) | bool |
like(Model $liker, Model $likeable) |
Ajoute un like (👍) | void |
unlike(Model $liker, Model $likeable) |
Supprime un like | void |
hasLiked(Model $liker, Model $likeable) |
Vérifie si l'utilisateur a réagi | bool |
countLikes(Model $likeable) |
Compte toutes les réactions | int |
countLikesByType(Model $likeable, LikeType $type) |
Compte les réactions par type | int |
getLikers(Model $likeable) |
Récupère tous les likeurs | Collection |
getLikersByType(Model $likeable, LikeType $type) |
Récupère les likeurs par type | Collection |
getLikerLikes(Model $liker) |
Récupère les réactions d'un utilisateur | Collection |
getLikerLikesByType(Model $liker, LikeType $type) |
Récupère les réactions d'un utilisateur par type | Collection |
getLikesUpdatedAfter(DateTimeVO $date) |
Récupère les réactions après une date | Collection |
getLikerLikesUpdatedAfter(Model $liker, DateTimeVO $date) |
Récupère les réactions d'un utilisateur après une date | Collection |
getLikesForLikeableUpdatedAfter(Model $likeable, DateTimeVO $date) |
Récupère les réactions d'un objet après une date | Collection |
🎯 Value Objects
Le package supporte les Value Objects suivants :
| Value Object | Description | Exemple |
|---|---|---|
DateTimeVO |
Date/heure | DateTimeVO::from('2024-01-01 12:00:00') |
StrictDataObject |
Métadonnées typées | StrictDataObject::from(['key' => 'value']) |
Accesseurs dans le modèle Like
$like = Like::find(1); // Accès sous forme de Value Objects $createdAt = $like->getCreatedAt(); // DateTimeVO $updatedAt = $like->getUpdatedAt(); // DateTimeVO $deletedAt = $like->getDeletedAt(); // DateTimeVO $metadata = $like->getMetadata(); // StrictDataObject $type = $like->getType(); // LikeType // Relations $liker = $like->liker; // Auteur (User, Admin, etc.) $likeable = $like->likeable; // Objet liké (Post, Article, etc.)
📝 Structure de la base de données
CREATE TABLE likes ( id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, liker_type VARCHAR(255) NOT NULL, -- Type de l'auteur liker_id BIGINT UNSIGNED NOT NULL, -- ID de l'auteur likeable_type VARCHAR(255) NOT NULL, -- Type de l'objet liké likeable_id BIGINT UNSIGNED NOT NULL,-- ID de l'objet liké type VARCHAR(20) DEFAULT 'like', -- like, love, haha, wow, sad, angry metadata JSON NULL, -- Métadonnées created_at TIMESTAMP NULL, updated_at TIMESTAMP NULL, deleted_at TIMESTAMP NULL, UNIQUE INDEX idx_unique_like (liker_type, liker_id, likeable_type, likeable_id), INDEX idx_liker (liker_type, liker_id), INDEX idx_likeable (likeable_type, likeable_id), INDEX idx_type (type), INDEX idx_updated_at (updated_at) );
🔍 Exemple complet
use AndyDefer\LaravelLikes\Services\LikeService; use AndyDefer\LaravelLikes\Enums\LikeType; class PostController extends Controller { public function __construct( private readonly LikeService $likeService ) {} public function react(Request $request, Post $post) { $user = $request->user(); $type = LikeType::tryFrom($request->input('type', 'like')); if (!$type) { return response()->json(['error' => 'Type de réaction invalide'], 400); } $reacted = $this->likeService->toggle($user, $post, $type); return response()->json([ 'reacted' => $reacted, 'type' => $reacted ? $type->value : null, 'emoji' => $reacted ? $type->getEmoji() : null, 'label' => $reacted ? $type->getLabel() : null, ]); } public function stats(Post $post) { $types = LikeType::cases(); $reactions = []; foreach ($types as $type) { $reactions[$type->value] = [ 'count' => $this->likeService->countLikesByType($post, $type), 'emoji' => $type->getEmoji(), 'label' => $type->getLabel(), ]; } return response()->json([ 'total' => $this->likeService->countLikes($post), 'reactions' => $reactions, ]); } public function likers(Post $post) { $likers = $this->likeService->getLikers($post); return response()->json($likers); } public function myReactions(Request $request) { $user = $request->user(); $type = LikeType::tryFrom($request->input('type')); if ($type) { $reactions = $this->likeService->getLikerLikesByType($user, $type); } else { $reactions = $this->likeService->getLikerLikes($user); } return response()->json($reactions); } }
🧪 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.
🔧 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 Repositoryandydefer/domain-structures- Structures de domaine (AbstractRecord, AbstractData)
👨💻 Auteur
Andy Kani
- GitHub: @andydefer
- Email: andykanidimbu@gmail.com
⭐ Support
Si vous trouvez ce package utile, n'hésitez pas à lui donner une ⭐ sur GitHub !
🙏 Remerciements
- Framework Laravel
- Tous les contributeurs et utilisateurs de ce package
Construit avec ❤️ pour la communauté Laravel
统计信息
- 总下载量: 0
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 3
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-06-19