Laravel Cart

Laravel Cart est un package hautement personnalisable qui vous permet d'ajouter facilement des fonctionnalités de panier d'achat à vos applications Laravel. Avec des options flexibles pour la gestion des articles, le stockage persistant et une intégration profonde avec Laravel, il est parfait pour construire des fonctionnalités de commerce électronique ou d'achats personnalisés.

Laravel cart

Total DownloadsLatest Version on Packagist

Caractéristiques

  • â Stockage persistant du panier (base de données/session)
  • â Support des utilisateurs invités et authentifiés
  • â Calculs de prix de haute précision
  • â Associations de modèles
  • â Enchaînement de méthodes
  • â Gestion des exceptions

Installation du paquet

Pour installer le paquet, utilisez Composer :

composer require isapp/laravel-cart

Publication de la configuration

Pour modifier la configuration par défaut, publiez le fichier de configuration en utilisant la commande Artisan suivante :

php artisan vendor:publish --provider="Isapp\LaravelCart\CartServiceProvider" --tag="config"

Cette commande créera un fichier config/laravel-cart.php dans lequel vous pourrez personnaliser les paramètres du package selon vos besoins.

Publication et exécution des migrations

Pour publier les fichiers de migration fournis par le paquet Laravel Cart, utilisez la commande Artisan suivante :

php artisan vendor:publish --provider="Isapp\LaravelCart\CartServiceProvider" --tag="migrations"

Cette commande copiera les fichiers de migration dans le répertoire database/migrations de votre projet.

Exécution des migrations

Une fois les fichiers de migration publiés, vous pouvez appliquer les migrations à votre base de données à l'aide de la commande suivante :

php artisan migrate

Mise en route

Gestion des utilisateurs

getUser(): ?Authenticatable

Renvoie l'utilisateur actuellement authentifié ou null si aucun utilisateur n'est défini.

$user = Cart::getUser();

setUser(Authenticatable $user): Driver

Définit un utilisateur spécifique pour les opérations de cart. Utile pour les opérations d'administration ou l'usurpation d'identité.

$user = User::find(1);
Cart::setUser($user)->storeItem($item);

setGuard(string $guard): Driver

Définit le gardien d'authentification à utiliser (la valeur par défaut est 'web').

Cart::setGuard('admin')->getUser();

Gestion du panier

get(): Model|Cart

Obtient ou crée le panier pour l'utilisateur ou la session en cours. Pour les utilisateurs authentifiés, la recherche ou la création du panier se fait à partir de l'identifiant de l'utilisateur. Pour les invités, utilise l'identifiant de session.

$cart = Cart::get();
echo "Cart has " . $cart->items->count() . " items";

Stockage des articles

storeItem(CartItemContract $item): Driver

Stocke un seul article dans le panier. Si l'article existe déjà, la quantité est augmentée.

$product = Product::find(1);
$cartItem = new CartItem();
$cartItem->itemable()->associate($product);
Cart::storeItem($cartItem);

Lance :

  • NotImplementedException - si itemable n'implémente pas CartItemProduct
  • ItemAssociatedWithDifferentCartException - si vous essayez d'ajouter un article provenant d'un autre panier

storeItems(Collection $items): static

Stocke plusieurs articles dans le panier en une seule fois.

$items = collect([
    $cartItem1,
    $cartItem2,
    $cartItem3
]);
Cart::storeItems($items);

Gestion des quantités

increaseQuantity(CartItemContract $item, int $quantity = 1): static

Augmente la quantité d'un article spécifique du panier.

// Increase by 1 (default)
Cart::increaseQuantity($cartItem);

// Increase by specific amount
Cart::increaseQuantity($cartItem, 5);

Lance :

  • NotFoundException - si l'article n'existe pas dans le panier

decreaseQuantity(CartItemContract $item, int $quantity = 1): Driver

Diminue la quantité d'un article spécifique du panier.

// Decrease by 1 (default)
Cart::decreaseQuantity($cartItem);

// Decrease by specific amount
Cart::decreaseQuantity($cartItem, 3);

Lance : si l'article n'existe pas dans le panier :

  • NotFoundException - si l'article n'existe pas dans le panier

Suppression d'un article

removeItem(CartItemContract $item): Driver

Supprime complètement un article spécifique du panier.

Cart::removeItem($cartItem);

emptyCart(): static

Supprime tous les articles du panier.

Cart::emptyCart();

Calcul des prix

getItemPrice(CartItemContract $item, bool $incTaxes = true): string

Calcule le prix total d'un article du panier (prix × quantité). Renvoie une chaîne de caractères pour plus de précision.

// With taxes (default)
$totalPrice = Cart::getItemPrice($cartItem);

// Without taxes
$totalPrice = Cart::getItemPrice($cartItem, false);

getItemPricePerUnit(CartItemContract $item, bool $incTaxes = true): string

Obtient le prix unitaire d'un article du panier.

// With taxes (default)
$unitPrice = Cart::getItemPricePerUnit($cartItem);

// Without taxes
$unitPrice = Cart::getItemPricePerUnit($cartItem, false);

getTotalPrice(bool $incTaxes = true): string

Calcule le prix total de tous les articles du panier.

// With taxes (default)
$total = Cart::getTotalPrice();

// Without taxes
$total = Cart::getTotalPrice(false);

Exemples d'utilisation

Opérations de base sur les paniers

use Isapp\LaravelCart\Facades\Cart;
use App\Models\Product;
use Isapp\LaravelCart\Models\CartItem;

// Create and add item to cart
$product = Product::find(1);
$cartItem = new CartItem();
$cartItem->itemable()->associate($product);

Cart::storeItem($cartItem);

// Get cart with items
$cart = Cart::get();
echo "Items in cart: " . $cart->items->count();

// Calculate totals
$total = Cart::getTotalPrice();
echo "Cart total: $" . $total;

Travailler avec différents utilisateurs

// Admin adding items to user's cart
$user = User::find(123);
$product = Product::find(1);
$cartItem = new CartItem();
$cartItem->itemable()->associate($product);

Cart::setUser($user)->storeItem($cartItem);

Gestion des quantités

// Get existing cart item
$cart = Cart::get();
$cartItem = $cart->items->first();

// Increase quantity
Cart::increaseQuantity($cartItem, 2);

// Decrease quantity
Cart::decreaseQuantity($cartItem, 1);

// Remove item completely
Cart::removeItem($cartItem);

Calcul des prix

$cart = Cart::get();

foreach ($cart->items as $item) {
    $unitPrice = Cart::getItemPricePerUnit($item);
    $totalItemPrice = Cart::getItemPrice($item);
    
    echo "Unit: $unitPrice, Total: $totalItemPrice\n";
}

$grandTotal = Cart::getTotalPrice();
echo "Grand Total: $grandTotal";

Gestion des erreurs

Le pilote de base de données lance des exceptions spécifiques pour différentes conditions d'erreur :

use Isapp\LaravelCart\Exceptions\NotFoundException;
use Isapp\LaravelCart\Exceptions\NotImplementedException;
use Isapp\LaravelCart\Exceptions\ItemAssociatedWithDifferentCartException;

try {
    Cart::increaseQuantity($cartItem, 5);
} catch (NotFoundException $e) {
    // Item not found in cart
    return response()->json(['error' => 'Item not found'], 404);
} catch (NotImplementedException $e) {
    // Itemable doesn't implement required interface
    return response()->json(['error' => 'Invalid item'], 400);
} catch (ItemAssociatedWithDifferentCartException $e) {
    // Trying to add item from another cart
    return response()->json(['error' => 'Item belongs to different cart'], 400);
}

Notes

  • Tous les calculs de prix utilisent BCMath pour une arithmétique de haute précision
  • Les prix sont renvoyés sous forme de chaînes de caractères afin de préserver la précision
  • Le pilote supporte à la fois les utilisateurs authentifiés et les sessions d'invités
  • Le chaînage de méthodes est pris en charge pour l'interface fluide
  • Les articles du panier doivent implémenter l'interface CartItemProduct
  • Le pilote utilise le chargement anticipé pour optimiser les requêtes de base de données

Ajouter un driver personnalisé à la façade Laravel via Extend

Si vous avez besoin d'ajouter un pilote personnalisé à la façade Cart, vous pouvez le faire en l'étendant dans un fournisseur de services. Voici un exemple qui montre comment procéder :

  1. Créez une classe de pilote personnalisée, par exemple :

    namespace App\Services;
    
    use Isapp\LaravelCart\Contracts\Driver;
    
    class CustomCartDriver implements Driver
    {
        // Implement methods as per the contract and your needs
        public function storeItem(CartItemContract $item): Driver
        {
            // Custom implementation
        }
    
        public function increaseQuantity(CartItemContract $item, int $quantity = 1): static
        {
            // Custom implementation
        }
    
        // Other required methods...
    }
    
  2. Enregistrez le pilote personnalisé dans un fournisseur de services :

    namespace App\Providers;
    
    use Illuminate\Support\ServiceProvider;
    use Isapp\LaravelCart\Facades\Cart;
    
    class CartServiceProvider extends ServiceProvider
    {
        public function boot()
        {
            Cart::extend('custom', function () {
                return new \App\Services\CustomCartDriver;
            });
        }
    }
    

Liste des choses à faire

  • Ajouter un nettoyage automatisé pour les sessions de panier expirées
  • Ajouter une méthode pour obtenir le nombre total d'articles dans le panier
  • Ajout d'une méthode pour obtenir la quantité totale de tous les articles
  • Ajout d'une méthode pour trouver un article par son ID
  • Ajout d'une méthode pour vérifier si un article spécifique existe dans le panier
  • Ajout de la validation du stock avant l'ajout d'articles
  • Ajout d'un déclenchement d'événements (ItemAdded, ItemRemoved, etc.)
  • Ajout d'une méthode pour fusionner les paniers (invité → utilisateur)

Contribuer

Les contributions sont les bienvenues ! Si vous avez des suggestions d'améliorations, de nouvelles fonctionnalités, ou si vous trouvez des problèmes, n'hésitez pas à soumettre une pull request ou à ouvrir un problème dans ce dépôt.

Merci de contribuer à l'amélioration de ce paquet pour la communauté !

Licence

Ce projet est un logiciel libre sous licence MIT.

Vous êtes libre de l'utiliser, de le modifier et de le distribuer dans vos projets, tant que vous respectez les termes de la licence.